/* ============================================================
   Gang Sheet Builder — v28 paper-light skin (override layer)
   Loads AFTER assets/main.css + src/styles.css. Pure CSS overrides —
   styles.css stays byte-identical to the live builder for diffing.
   Language: paper stock surfaces, ink chrome bars, CMYK process
   accents, Space Mono press readouts. Tokens from site-v28 tokens.css.
   ============================================================ */

:root {
  /* Brand → CMYK process */
  --color-primary:        #00a7e1;
  --color-primary-dark:   #007bb0;
  --color-primary-light:  #43c3f0;
  --color-primary-ghost:  rgba(0, 167, 225, 0.09);

  /* Neutral ramp → ink on paper */
  --color-secondary:      #151310;
  --color-secondary-mid:  #2b2721;
  --color-900:            #151310;
  --color-800:            #38332b;
  --color-600:            #6f6759;
  --color-400:            #b9b09b;
  --color-300:            #d8d0bd;
  --color-200:            #e6dfcd;
  --color-100:            #f7f2e6;

  --color-accent:         #ff5a1f;
  --color-accent-dark:    #d94614;

  /* Type → v28 stack */
  --font-heading:         'Syne', sans-serif;
  --font-body:            'Space Grotesk', system-ui, sans-serif;
  --font-mono:            'Space Mono', monospace;

  /* Brutalist flattening */
  --radius-sm: 3px;
  --radius-md: 5px;
  --radius-lg: 8px;

  /* Semantic aliases — declared here too so the skin stands alone even
     without the old theme main.css (v28 integration won't ship it). */
  --color-text:        var(--color-900);
  --color-text-muted:  var(--color-600);
  --color-bg:          var(--color-100);
  --color-bg-subtle:   var(--color-200);
  --color-bg-dark:     var(--color-secondary);
  --color-border:      var(--color-300);
  --color-success:     #1e9e50;
  --color-warning:     #c25a1a;
  --color-error:       #c22f2f;
  --color-info:        #007bb0;
}

/* ── Base (old main.css no longer loads — carry its resets) ── */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-family: var(--f-body, 'Space Grotesk', sans-serif); color: #151310; -webkit-font-smoothing: antialiased; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.page-progress { display: none; }
.form-group { margin-bottom: 14px; }
.form-group label { display: block; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; margin-bottom: 6px; color: var(--color-text); }

/* ── Page + workspace surfaces ── */
body { background: #efe9db; }
.gs-app { background: #efe9db; }
.gs-app-header {
  background: #f7f2e6;
  border-bottom: 2px solid var(--color-900);
  box-shadow: none;
}
.gs-app-title { text-transform: uppercase; letter-spacing: .06em; }

/* The deck around the sheet = light table */
.gs-canvas-viewport { background: #e6dfcd; }
/* The sheet itself — hard ink offset shadow, a stack of printed film */
.gs-canvas-outer {
  box-shadow: 10px 10px 0 rgba(21, 19, 16, .16), 0 0 0 1px rgba(21, 19, 16, .28);
}

/* ── Status bar = press readout strip (ink + mono) ── */
.gs-status-bar {
  background: #151310;
  border-top-color: rgba(239, 233, 219, .08);
}
.gs-status-bar, .gs-status-bar * { font-family: var(--font-mono); }

/* Ruler strips + corner readout: slate → ink */
.gs-ruler-corner, .gs-ruler-x, .gs-ruler-y { background: #151310; }
/* Issues popover + preview dialog body: slate → ink / light table */
.gs-issues-pop { background: #151310; }
.gs-preview-dialog__body { background: #e6dfcd; }

/* ── Price box = meter reading (ink block, cyan figure) ── */
.gs-price-box {
  background: #151310;
  border: 2px solid #151310;
  border-radius: var(--radius-md);
  box-shadow: 5px 5px 0 rgba(21, 19, 16, .18);
}
.gs-price-box::before { background: radial-gradient(circle, rgba(0, 167, 225, .22) 0%, transparent 70%); }
.gs-price-box .gs-price-value,
.gs-price-box [id*="price"] { font-family: var(--font-mono); }

/* ── Primary actions: process cyan, ink border, hard shadow ── */
.gs-submit-btn {
  background: var(--color-primary);
  color: #151310;
  border: 2px solid #151310;
  box-shadow: 4px 4px 0 #151310;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.gs-submit-btn:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: 5px 5px 0 #151310; }
.gs-submit-btn:active:not(:disabled) { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #151310; }
.gs-hdr-btn--primary {
  background: var(--color-primary);
  border-color: #151310;
  color: #151310;
  box-shadow: 2px 2px 0 #151310;
}
.gs-hdr-btn--primary:hover { opacity: 1; color: #151310; transform: translate(-1px, -1px); box-shadow: 3px 3px 0 #151310; }

/* Old dark-cyan (#0D9CB8) gradient CTAs → process pair (were !important) */
body.is-mobile .gs-mob-fab-build,
#gs-mob-fab-build {
  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%) !important;
  color: #151310 !important;
}

/* ── Dark-slate remnants → ink ── */
.ifgs-cart-pill { background: #151310; }
.ifgs-cart-popover { background: #f7f2e6; border: 2px solid #151310; box-shadow: 6px 6px 0 rgba(21, 19, 16, .18); }
.ifgs-toast { background: #151310; color: #efe9db; font-family: var(--font-body); }
.gs-tour-tooltip { background: #f7f2e6; border: 2px solid #151310; box-shadow: 6px 6px 0 rgba(21, 19, 16, .2); }
.gs-tour-btn--primary { background: var(--color-primary); color: #151310; }
.gs-reorder-banner, .gs-prefill-badge { background: #151310; color: #efe9db; }
.gs-floating-toolbar { background: #151310; }

/* Sidebar icon rails: slate navy → ink blocks */
.gs-sidebar__icons { background: #151310; border-right-color: rgba(239, 233, 219, .08); }
/* Sidebar panels: hard-coded #fff → panel paper */
.gs-sidebar__panels { background: #f7f2e6; }
.gs-q-hint { background: #151310; }

/* Mobile shell chrome → v28 paper (matches the merch mobile shell so both
   builders read as one system). The old rules painted the bars ink/slate;
   these repaint to paper stock with ink borders, muted-ink icons + cyan active.
   NOTE: the tab-rail rule must out-specify styles.css `.gs-sidebar--left
   .gs-sidebar__icons` (0,3,1 !important) — matched here + later in source order. */
body.is-mobile .gs-app { background: #efe9db !important; }
body.is-mobile .gs-canvas-viewport { background: #e6dfcd !important; }

/* bottom tab rail */
body.is-mobile .gs-sidebar--left .gs-sidebar__icons {
  background: #f7f2e6 !important;
  border-top: 2px solid #151310 !important;
  box-shadow: 0 -6px 22px rgba(21, 19, 16, .14) !important;
}
body.is-mobile .gs-sidebar__icon-btn,
body.is-mobile .gs-sidebar__icon-btn .gs-sidebar__icon-label { color: #6f6759 !important; }
body.is-mobile .gs-sidebar__icon-btn.is-active,
body.is-mobile .gs-sidebar__icon-btn.is-active .gs-sidebar__icon-label { color: #00a7e1 !important; }

/* persistent order-status pill → paper */
body.is-mobile #ifgs-cart-pill.ifgs-cart-pill {
  background: #f7f2e6 !important; color: #151310 !important; border: 1.5px solid #151310 !important;
}
body.is-mobile #ifgs-cart-pill .ifgs-cart-total { color: #00a7e1 !important; }

/* "View order" CTA (portrait) → flat cyan + ink + hard shadow == merch Add-to-cart */
body.is-mobile #mob-cart-pill.gs-mob-cart-pill {
  background: #00a7e1 !important; background-image: none !important; color: #151310 !important;
  border: 2px solid #151310 !important; box-shadow: 3px 3px 0 #151310 !important; border-radius: 10px !important;
}
body.is-mobile #mob-cart-pill .gs-mob-cart-pill__label,
body.is-mobile #mob-cart-pill .gs-mob-cart-pill__price,
body.is-mobile #mob-cart-pill .gs-mob-cart-pill__cents,
body.is-mobile #mob-cart-pill .gs-mob-cart-pill__arrow { color: #151310 !important; }

/* landscape cart-with-price (replaces the portrait pill) → same flat cyan + ink */
body.is-mobile.is-landscape-mobile .gs-mob-toolbar-cart {
  background: #00a7e1 !important; background-image: none !important; color: #151310 !important;
  border: 2px solid #151310 !important; box-shadow: 2px 2px 0 #151310 !important;
}
body.is-mobile.is-landscape-mobile .gs-mob-toolbar-cart-price,
body.is-mobile.is-landscape-mobile .gs-mob-toolbar-cart .material-symbols-rounded { color: #151310 !important; }

/* reorder banner → paper */
body.is-mobile #gs-reorder-banner { background: #e6dfcd !important; color: #151310 !important; }

/* Pinch on the shell must never zoom the page. The locked viewport handles this on
   Android, but iOS Safari ignores user-scalable=no — so suppress touch-zoom on the
   always-visible chrome directly (taps/clicks still fire; drawers keep pan scroll,
   the canvas keeps its own IFBuilderMobile gesture layer). */
body.is-mobile .gs-app-header,
body.is-mobile .gs-sidebar__icons,
body.is-mobile .gs-sidebar__icon-btn,
body.is-mobile #mob-cart-pill,
body.is-mobile .gs-mob-cart-pill,
body.is-mobile #gs-mob-fab-build,
body.is-mobile .gs-mob-fab { touch-action: none; }

/* ── Numeric readouts in mono ── */
.gs-dim-chip, .gs-size-btn__sub, .ifgs-cart-total, .ifgs-cart-popover__total { font-family: var(--font-mono); }

/* ══════════════════════════════════════════════════════════
   v28 CHROME — header + footer, ported from site-v28
   (tokens.css + layout.css). Markup in the shell mirrors
   partials/nav.njk + partials/footer.njk.
   ══════════════════════════════════════════════════════════ */
/* THE TOKENS ARE NOT REDECLARED HERE ANY MORE — Tokens v2, 2026-09-01.
   This block was an eleven-token copy of site-v28/css/tokens.css, kept because
   page-gangsheet.php did not load the real file. The values were identical, so
   nothing looked wrong; it was a second implementation waiting to drift.

   It had already drifted. Measured on staging before the change, the builder
   resolved --paper/--ink/--cyan/--mag/--yel and the three faces correctly and
   left --line, --orange and --mag-on-paper UNDEFINED — three tokens marketing
   has had for weeks. Bare var(--line) in a rule loaded here would have silently
   computed to nothing (feedback_css_var_chain_silent_failure), and the next
   person needing a semantic colour would have pasted a fourth green in here.

   page-gangsheet.php now enqueues tokens.css ahead of this file, so there is one
   token layer. --v28-orange is dropped rather than renamed: it was declared here
   and referenced nowhere. */

/* line-hover link */
.lh { position: relative; }
.lh::after {
  content: ""; position: absolute; left: 0; bottom: -3px; width: 100%; height: 2.5px;
  background: var(--ink); transform: scaleX(0); transform-origin: right; transition: transform 0.3s var(--ease);
}
.lh:hover::after { transform: scaleX(1); transform-origin: left; }

/* nav */
header.site-header { position: sticky; top: 0; z-index: 900; background: var(--paper); border-bottom: 2px solid var(--ink); }
.nav { max-width: var(--maxw); margin: 0 auto; padding: 14px 48px; display: flex; align-items: center; justify-content: space-between; }
.nav a { color: var(--ink); text-decoration: none; font-family: var(--f-body); }
.brand {
  font-family: var(--f-display); font-weight: 800; font-size: 22px; letter-spacing: -0.02em;
  text-transform: uppercase; display: flex; align-items: center; gap: 10px;
  color: var(--ink); text-decoration: none;
}
.brand .sq { display: flex; gap: 2px; }
.brand .sq i { width: 7px; height: 18px; }
.brand .sq i:nth-child(1) { background: var(--cyan); }
.brand .sq i:nth-child(2) { background: var(--mag); }
.brand .sq i:nth-child(3) { background: var(--yel); }
.nav .links { display: flex; gap: 22px; align-items: center; }
.nav .links a { font-weight: 600; font-size: 14px; }
.nav .cta {
  font-weight: 700; font-size: 14px; background: var(--ink); color: var(--paper);
  padding: 11px 20px; border: 2px solid var(--ink); box-shadow: 4px 4px 0 var(--cyan); transition: 0.15s;
}
.nav .cta:hover { box-shadow: 2px 2px 0 var(--mag); transform: translate(2px, 2px); }
/* burger: the builder has its own mobile shell — no marketing menu here */
.nav .burger { display: none; }
/* 820 was STALE. The site moved this breakpoint 820 -> 1100 -> 1240 (the
   arithmetic is in site-v28/css/layout.css: wordmark 246 + link row 799 + cart
   44 + 96 padding = a 1185px minimum, so it collapses at --maxw 1240). The
   builder renders the same site header but does NOT load layout.css, so it kept
   the 2026-08 value and showed the full desktop nav down to 821px — 97px of real
   horizontal page scroll at 835px, because .links stayed 587px wide and pushed
   the header cart out to 932px.
   Matching 1240 keeps the builder consistent with every other page. The burger
   stays hidden by the deliberate decision above; the CTA and the cart remain,
   and the footer carries the full nav. */
@media (max-width: 1240px) {
  .nav .links a:not(.cta) { display: none; }
  .nav { padding: 14px 20px; }
}

/* footer */
.v28-footer { background: var(--ink); color: var(--paper); padding: 64px 0 34px; font-family: var(--f-body); }
.v28-footer .wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 48px; }
.v28-footer a { text-decoration: none; }
.fgrid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 30px; margin-bottom: 44px; }
.fgrid h5 { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.16em; color: #b7b1a4; text-transform: uppercase; margin: 0 0 16px; }
.fgrid a { display: inline-block; color: #e6dfcd; font-size: 14px; padding: 5px 0; }
.fbrand .brand { color: var(--paper); margin-bottom: 14px; }
.fbrand p { color: #b7b1a4; font-size: 14px; max-width: 280px; margin: 0; }
.colophon {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px;
  font-family: var(--f-mono); font-size: 11px; color: #8f897c; letter-spacing: 0.06em;
  padding-top: 22px; border-top: 2px solid rgba(239, 233, 219, 0.16);
}
.v28-footer .lh::after { background: var(--yel); }
@media (max-width: 820px) { .fgrid { grid-template-columns: 1fr 1fr; } .v28-footer .wrap { padding: 0 20px; } }
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 10000;
  background: #151310; color: #efe9db; padding: 8px 14px; text-decoration: none;
}
.skip-link:focus { left: 8px; top: 8px; }

/* Notice strip under the hero is inline-styled in the verbatim markup
   (#eff9fc ice blue) — re-paper it without touching the markup. */
div[style*="#eff9fc"] {
  background: #e6dfcd !important;
  border-bottom: 1px solid rgba(21, 19, 16, .2) !important;
  color: #151310 !important;
  font-family: 'Space Grotesk', system-ui, sans-serif !important;
}

/* Logo CMYK bars: on-load "print-in" entrance (staggered, once per page load). */
@keyframes ifSqPrintIn {
  0%   { transform: scaleY(0);    opacity: 0; }
  60%  { transform: scaleY(1.15); opacity: 1; }
  100% { transform: scaleY(1);    opacity: 1; }
}
.brand .sq i {
  transform-origin: bottom center;
  animation: ifSqPrintIn .55s cubic-bezier(.2, .75, .3, 1) both;
}
.brand .sq i:nth-child(1) { animation-delay: .05s; }
.brand .sq i:nth-child(2) { animation-delay: .16s; }
.brand .sq i:nth-child(3) { animation-delay: .27s; }
@media (prefers-reduced-motion: reduce) { .brand .sq i { animation: none; } }
/* ============================================================
   v28 FULL PAPER + BRUTALIST (2026-07-13) — converts the remaining dark
   "app" blocks (price box, floating toolbar, icon rail, status bar, dim
   chip, issues popover, reorder banner) to paper stock + ink borders +
   hard offset shadows, matching the marketing pages. Ruler canvas colours
   live in canvas-init.js drawRulers().
   ============================================================ */
.gs-price-box { background: #f7f2e6 !important; border: 2px solid #151310 !important; box-shadow: 6px 6px 0 rgba(21,19,16,.16) !important; }
.gs-price-box::before { display: none !important; }
.gs-price-label { color: #007bb0 !important; }
.gs-price-amount, .gs-price-amount *, .gs-price-box [id*="price"] { color: #151310 !important; }
/* :not([role=radio]) — the turnaround buttons set their own fg/bg pair and this
   universal !important was overriding them, leaving #4a453b on #151310 (1.94:1)
   on the SELECTED button. Row text keeps the colour; controls opt out. */
.gs-price-box .gs-price-row, .gs-price-box .gs-price-row *:not([role="radio"]) { color: #4a453b !important; }
.gs-price-sub { color: #6f6759 !important; }

.gs-floating-toolbar { background: #f7f2e6 !important; border: 2px solid #151310 !important; box-shadow: 4px 4px 0 rgba(21,19,16,.16) !important; border-radius: 10px !important; }
.gs-floating-toolbar, .gs-floating-toolbar button, .gs-floating-toolbar span:not(.material-symbols-rounded) { color: #151310 !important; }
.gs-floating-toolbar .is-active, .gs-floating-toolbar [class*="active"] { color: #00a7e1 !important; }

.gs-sidebar__icons { background: #f7f2e6 !important; border-right: 2px solid #151310 !important; }
.gs-sidebar__panels { border-right: 2px solid #151310 !important; }

.gs-status-bar { background: #f7f2e6 !important; border-top: 2px solid #151310 !important; }
.gs-status-bar, .gs-status-bar * { color: #151310 !important; }

.gs-dim-chip { background: #f7f2e6 !important; border: 1.5px solid #151310 !important; color: #151310 !important; }

.gs-issues-pop { background: #f7f2e6 !important; border: 2px solid #151310 !important; box-shadow: 6px 6px 0 rgba(21,19,16,.18) !important; }
.gs-issues-pop * { color: #151310 !important; }

.gs-reorder-banner { background: #e6dfcd !important; border-bottom: 2px solid #151310 !important; }
.gs-reorder-banner * { color: #151310 !important; }

.gs-size-btn { border: 2px solid #151310 !important; box-shadow: 3px 3px 0 rgba(21,19,16,.14) !important; }
.gs-size-btn.is-active { border-color: #00a7e1 !important; box-shadow: 3px 3px 0 #00a7e1 !important; background: rgba(0,167,225,.08) !important; }

.gs-hdr-btn { border: 1.5px solid #151310 !important; box-shadow: 2px 2px 0 rgba(21,19,16,.16) !important; }
.gs-hdr-btn:hover { transform: translate(-1px,-1px) !important; box-shadow: 3px 3px 0 rgba(21,19,16,.16) !important; }

.gs-submit-btn:not(:disabled) { box-shadow: 4px 4px 0 #151310 !important; }
/* ============================================================
   v28 PAPER REBUILD - follow-ups (2026-07-13):
   1) left icon-rail SVGs were white (invisible on paper) -> ink;
   2) paper halftone texture, identical to marketing base.css body::before;
   3) brand logo font: the .nav a { font-family:var(--f-body) } rule was
      more specific than .brand, dropping it to Space Grotesk -> force Syne.
   ============================================================ */

/* 1. Left icon rail: icons + labels readable on paper */
.gs-sidebar__icon-btn { color: #6f6759 !important; }
.gs-sidebar__icon-btn:hover { background: rgba(21,19,16,.06) !important; color: #151310 !important; }
.gs-sidebar__icon-btn.is-active { background: rgba(0,167,225,.12) !important; color: #00a7e1 !important; }
/* mobile shell rail (was light grey #cfd8e3 on paper) */
body.is-mobile .gs-sidebar--left .gs-sidebar__icon-btn { color: #6f6759 !important; }
body.is-mobile .gs-sidebar--left .gs-sidebar__icon-btn.is-active { color: #00a7e1 !important; }

/* 2. Paper halftone texture (matches marketing site-v28 base.css body::before) */
body::before {
  /* V4 — z-index 9998 -> -1, ATOMICALLY with the three lifts it caused.
     At 9998 with mix-blend-mode:multiply this sat over EVERYTHING, the
     customer's artwork included, where it moires against their own halftones.
     The 9999 / 10001 / 10005-10030 values below existed purely to climb over
     it, and a partial fix once left the mobile drawers blank. */
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: .4;
  background-image: radial-gradient(rgba(21,19,16,.14) 1px, transparent 1.3px);
  background-size: 6px 6px; mix-blend-mode: multiply;
}

/* 3. Brand logo uses the display face (Syne) like marketing */
.nav a.brand, .brand { font-family: var(--f-display) !important; }
/* Paper texture must NOT fall on the working canvas. The texture is a
   z-9998 top overlay (so it covers all chrome uniformly, like marketing);
   lift the whole canvas work-area above it - the sheet, rulers, on-canvas
   floating toolbar (z20) and zoom pill (z25) all rise together and stay
   clean. Interactive overlays that can appear OVER the canvas are lifted
   above the raised area so they are never hidden behind the sheet.
   (Cart pill/popover + Save menu sit over the right column - no overlap.) */
/* V4: the lift is gone — there is nothing to climb over now. position:relative
   stays for the sake of this element's absolutely-positioned children; the
   overlays that were pushed to 10001 to clear it return to their own values. */
.gs-canvas-area { position: relative; }
/* V4 (2026-08-28): the mobile chrome tower is gone too, and this is the half
   that must not be forgotten.
   It read: "the z-9999 canvas lift above (added with the paper texture) sits
   ABOVE the mobile slide-up panels (z 9005-9030), so on the mobile shell the
   working canvas painted OVER an open drawer - tapping a tab showed a blank
   area." That was a SHIPPED bug, patched by lifting seven selectors to
   10005-10030. With the canvas lift removed the panels' own 9005-9030 ordering
   is correct again, and keeping these would just be a second tower to maintain.
   Removing them WITHOUT removing the canvas lift is exactly the partial fix
   that blanked the drawers - hence one commit, and a phone pass. */
/* ============================================================
   Canvas-tool toolbar DOCKED into the header row (2026-07-13).
   Was a pill floating over the top of the sheet; header-dock.js moves the
   node into .gs-app-header before the document actions. Restyle it from a
   floating pill to an inline header group whose buttons match .gs-hdr-btn
   (brutalist paper). Mobile still hides .gs-floating-toolbar entirely.
   ============================================================ */
.gs-floating-toolbar--docked {
  position: static !important; transform: none !important; left: auto !important; top: auto !important;
  z-index: auto !important; background: none !important; border: none !important;
  box-shadow: none !important; border-radius: 0 !important; padding: 0 !important;
  backdrop-filter: none !important; gap: 6px !important;
}
.gs-floating-toolbar--docked .gs-ft-divider { display: none !important; }
.gs-floating-toolbar--docked .gs-ft-btn {
  padding: 5px 12px !important; font-size: 11px !important; font-weight: 700;
  font-family: var(--f-display); border-radius: 7px !important;
  border: 1.5px solid #151310 !important; background: #f7f2e6 !important; color: #151310 !important;
  box-shadow: 2px 2px 0 rgba(21,19,16,.16) !important;
  display: inline-flex; align-items: center; gap: 4px; transition: transform .12s, box-shadow .12s, background .12s;
}
.gs-floating-toolbar--docked .gs-ft-btn:hover {
  transform: translate(-1px,-1px); box-shadow: 3px 3px 0 rgba(21,19,16,.16) !important; background: #efe9db !important; color: #151310 !important;
}
.gs-floating-toolbar--docked .gs-ft-btn--build {
  /* White on #00a7e1 is 2.76:1 — below WCAG AA (4.5:1) on the button that
     builds the sheet, i.e. the money path. Ink on the same cyan is 6.73:1, and
     it matches the site's own .btn.fill, which is cyan with ink text.
     The hover below keeps white because #007bb0 + white is 4.71:1, which does
     pass; the light→dark inversion is deliberate. */
  background: #00a7e1 !important; color: #151310 !important; box-shadow: 2px 2px 0 #007bb0 !important;
}
.gs-floating-toolbar--docked .gs-ft-btn--build:hover { background: #007bb0 !important; color: #ffffff !important; }
.gs-floating-toolbar--docked .gs-ft-btn--danger { color: #c22f2f !important; }
.gs-floating-toolbar--docked .gs-ft-btn--danger:hover { background: #f7e4e4 !important; color: #c22f2f !important; }
/* ============================================================
   Zoom pill -> v28 (2026-07-13). Was a white fully-round pre-v28 pill with
   an orange % floating dead-centre. Repaint to paper + ink border + hard
   brutalist shadow + Space Mono %, and (desktop only) move it to the
   bottom-RIGHT corner, out of the way. Mobile position left untouched so it
   never collides with the mobile CTA bar / build FAB.
   ============================================================ */
.gs-zoom-pill {
  background: #f7f2e6 !important; border: 2px solid #151310 !important;
  border-radius: 10px !important; box-shadow: 3px 3px 0 rgba(21,19,16,.16) !important;
  padding: 3px 5px !important;
}
.gs-zoom-btn { color: #151310 !important; border-radius: 7px !important; }
.gs-zoom-btn:hover { background: rgba(21,19,16,.08) !important; color: #00a7e1 !important; }
.gs-zoom-pct { color: #151310 !important; font-family: var(--f-mono) !important; }
/* desktop: park it in the bottom-right corner instead of dead-centre */
body:not(.is-mobile) .gs-zoom-pill { left: auto !important; right: 16px !important; transform: none !important; }

/* =============================================================================
   DARK APP-SHELL RESTYLE (mock chrome) — added 2026-07-27
   Reversible: delete from this banner to EOF to restore the light-paper chrome.
   Colour / border / shadow only — NO layout dimensions touched. Desktop only
   (mobile rail keeps its own layout; handled separately).
   ============================================================================= */

/* -- Header bar -> dark ink ------------------------------------------------- */
.gs-app-header { background:#151310 !important; border-bottom:2.5px solid #151310 !important; }
.gs-app-header .gs-app-title,
.gs-app-breadcrumb, .gs-app-breadcrumb a, .gs-app-header__left a { color:#efe9db !important; }
.gs-app-breadcrumb a:hover { color:#00a7e1 !important; }
.gs-app-sep { color:#8a857a !important; }
.gs-app-header .gs-hdr-btn { background:#2a2620 !important; color:#e9e4d6 !important; border:1.5px solid #3a352c !important; box-shadow:none !important; }
.gs-app-header .gs-hdr-btn:hover { background:#38332b !important; color:#fff !important; transform:translate(-1px,-1px) !important; box-shadow:2px 2px 0 rgba(0,0,0,.45) !important; }
/* was color:#fff on cyan — 2.76:1. Ink is 6.73:1. */
.gs-app-header .gs-hdr-btn.is-active { background:#00a7e1 !important; border-color:#00a7e1 !important; color:#151310 !important; }
.gs-app-header .gs-hdr-btn--save { background:#ffd400 !important; border-color:#151310 !important; color:#151310 !important; }
.gs-hdr-divider { background:#3a352c !important; }

/* -- Left + right icon rails -> dark, cyan active edge ---------------------- */
.gs-sidebar--left  .gs-sidebar__icons { background:#1c1a15 !important; border-right:2.5px solid #151310 !important; }
.gs-sidebar--right .gs-sidebar__icons { background:#1c1a15 !important; border-left:2.5px solid #151310 !important; border-right:none !important; }
.gs-sidebar__icon-btn { color:#a9a396 !important; border-left:3px solid transparent !important; }
.gs-sidebar__icon-btn:hover { background:#2a2620 !important; color:#efe9db !important; }
.gs-sidebar__icon-btn.is-active { background:#2a2620 !important; color:#fff !important; border-left-color:#00a7e1 !important; }
.gs-sidebar__icon-btn.is-active .gs-sidebar__icon-label,
.gs-sidebar__icon-btn.is-active .material-symbols-rounded { color:#00a7e1 !important; }

/* -- Canvas workspace -> LIGHT gray diagonal (matches the artifact) -------- */
.gs-canvas-viewport { background:#e7e1d2 !important; background-image:repeating-linear-gradient(45deg,#e7e1d2,#e7e1d2 14px,#e2dbcb 14px,#e2dbcb 28px) !important; }

/* -- Price box -> light card with a YELLOW selected-size card ------------- */
.gs-price-box { background:#fffdf8 !important; border:2.5px solid #151310 !important; box-shadow:5px 5px 0 #151310 !important; }
.gs-price-box::before { display:none !important; }
.gs-price-topcard { display:flex !important; flex-direction:row !important; justify-content:space-between !important; align-items:center !important; gap:10px !important;
  background:#ffd400 !important; border:2.5px solid #151310 !important; padding:11px 13px !important; margin-bottom:14px !important; }
/* THE SHEET NAME AND THE PRICE COLLIDED. Measured on production at every
   desktop width, 1440 and 1920 alike: the card is a fixed ~205px, "STANDARD"
   needs 157px at 17px Syne 800, and the left column was handed 101px. With
   `min-width:0` the column shrank below its content and `white-space:nowrap`
   plus `overflow:visible` did the rest -- the name ran straight under the $14.
   Wrapping the flex line instead of shrinking the column fixes it for all nine
   names (checked one by one, including ROAD TRAIN and TRUCKLOAD): the price
   drops to its own row, the card settles at a stable 91px, and nothing is
   clipped. min-content is the floor that makes the wrap happen; without it the
   column would keep shrinking rather than pushing the price down. */
.gs-price-topcard { flex-wrap: wrap !important; row-gap: 6px !important; }
.gs-price-topcard__l { display:flex !important; flex-direction:column !important; min-width:min-content !important; flex:1 1 auto !important; }
.gs-price-name { font-family:var(--font-heading,'Syne',sans-serif) !important; font-weight:800 !important; font-size:17px !important; line-height:1 !important;
  text-transform:uppercase !important; letter-spacing:-.4px !important; color:#151310 !important; white-space:nowrap !important; }
.gs-price-topcard .gs-price-sub { font-family:var(--font-mono,'Space Mono',monospace) !important; font-weight:400 !important; font-size:10.5px !important;
  line-height:1.2 !important; color:#3a352c !important; margin-top:3px !important; text-transform:none !important; letter-spacing:0 !important; white-space:nowrap !important; }
.gs-price-topcard .gs-price-amount { display:inline-block !important; width:auto !important; text-align:right !important;
  font-family:var(--font-heading,'Syne',sans-serif) !important; font-weight:800 !important; font-size:26px !important;
  line-height:1 !important; color:#151310 !important; white-space:nowrap !important; flex:0 0 auto !important; margin:0 !important; }
/* Cents are omitted by the component when they are .00 (see ui/order-rail.js).
   This rule used to be `display:none !important`, which hid REAL cents too:
   with express turnaround a $16.80 sheet rendered as "$16". CSS cannot see a
   value, so hiding cents in the stylesheet can only ever hide all of them. */
.gs-price-topcard #price-dollars, .gs-price-topcard #price-cents, .gs-price-topcard .cents { color:#151310 !important; }

/* YOUR SHEET eyebrow */
.gs-yoursheet { font-family:var(--font-mono,'Space Mono',monospace) !important; font-size:11px !important; font-weight:700 !important;
  letter-spacing:.14em !important; text-transform:uppercase !important; color:#4a463d !important; margin-bottom:10px !important; }
/* breakdown rows */
.gs-price-breakdown { margin-top:14px !important; }
.gs-price-row { display:flex !important; justify-content:space-between !important; padding:7px 0 !important; border-bottom:1px dashed #e0d9c8 !important;
  font-family:var(--font-mono,'Space Mono',monospace) !important; font-size:12px !important; color:#4a463d !important; }
.gs-price-row:last-child { border-bottom:0 !important; }
.gs-price-row span:last-child { font-weight:700 !important; color:#151310 !important; }
/* Sheets stepper */
.gs-sheets-row { display:flex !important; justify-content:space-between !important; align-items:center !important; margin-top:16px !important; }
.gs-sheets-label { font-family:var(--font-mono,'Space Mono',monospace) !important; font-size:11px !important; font-weight:700 !important;
  letter-spacing:.1em !important; text-transform:uppercase !important; color:#4a463d !important; }
.gs-qty { display:flex !important; align-items:center !important; border:2.5px solid #151310 !important; }
.gs-qty-btn { width:34px !important; height:34px !important; background:#fffdf8 !important; border:0 !important; font-family:var(--font-heading,'Syne',sans-serif) !important;
  font-weight:800 !important; font-size:18px !important; color:#151310 !important; cursor:pointer !important; line-height:1 !important; padding:0 !important; }
.gs-qty-btn:hover { background:#ffd400 !important; }
.gs-qty .ifgs-qty-input { width:46px !important; height:34px !important; text-align:center !important; border:0 !important;
  border-left:2.5px solid #151310 !important; border-right:2.5px solid #151310 !important; border-radius:0 !important;
  font-family:var(--font-mono,'Space Mono',monospace) !important; font-weight:700 !important; font-size:14px !important; background:#fffdf8 !important; -moz-appearance:textfield !important; }
.gs-qty .ifgs-qty-input::-webkit-outer-spin-button, .gs-qty .ifgs-qty-input::-webkit-inner-spin-button { -webkit-appearance:none !important; margin:0 !important; }
/* Total */
.gs-total-row { display:flex !important; justify-content:space-between !important; align-items:baseline !important; margin-top:16px !important; padding-top:14px !important; border-top:2.5px solid #151310 !important; }
.gs-total-label { font-family:var(--font-mono,'Space Mono',monospace) !important; font-size:11px !important; text-transform:uppercase !important; letter-spacing:.1em !important; color:#4a463d !important; }
.gs-total-amt { font-family:var(--font-heading,'Syne',sans-serif) !important; font-weight:800 !important; font-size:30px !important; letter-spacing:-1px !important; color:#151310 !important; }
/* Auto-pack button */
.gs-autopack-btn { display:block !important; width:100% !important; margin-top:16px !important; padding:12px !important; background:#fffdf8 !important; color:#151310 !important;
  border:2.5px solid #151310 !important; box-shadow:4px 4px 0 #151310 !important; font-family:var(--font-heading,'Syne',sans-serif) !important; font-weight:800 !important;
  font-size:14px !important; text-transform:uppercase !important; letter-spacing:.02em !important; cursor:pointer !important; }
.gs-autopack-btn:hover { background:#ffd400 !important; transform:translate(-1px,-1px) !important; box-shadow:5px 5px 0 #151310 !important; }
.gs-autopack-btn:active { transform:translate(2px,2px) !important; box-shadow:2px 2px 0 #151310 !important; }
/* size cells: name / dims / price + solid-cyan active */
.gs-size-btn { text-align:left !important; }
.gs-size-btn__name { display:block !important; font-family:var(--font-heading,'Syne',sans-serif) !important; font-weight:800 !important; font-size:13px !important;
  text-transform:uppercase !important; letter-spacing:-.3px !important; color:#151310 !important; line-height:1 !important; }
.gs-size-btn__dims { display:block !important; font-family:var(--font-mono,'Space Mono',monospace) !important; font-size:9.5px !important; color:#6f6a5f !important; margin-top:2px !important; /* was #8a857a — 3.29:1 on the tile ground, now 4.82:1 */ }
.gs-size-btn__price { display:block !important; font-family:var(--font-heading,'Syne',sans-serif) !important; font-weight:800 !important; font-size:15px !important; color:#151310 !important; margin-top:5px !important; }
.gs-size-btn.is-active { background:#00a7e1 !important; border-color:#151310 !important; box-shadow:4px 4px 0 #151310 !important; }
/* INK, not white: #fff on cyan #00a7e1 is 2.76:1 — the ACTIVE size, the one a
   customer has just chosen, was the least readable tile on the page. Ink is 6.72:1. */
.gs-size-btn.is-active .gs-size-btn__name, .gs-size-btn.is-active .gs-size-btn__dims, .gs-size-btn.is-active .gs-size-btn__price { color:#151310 !important; }

/* -- Header toolbar cleanup (exact-match) — hide extras -------------------- */
/* Build Sheet -> now the rail's Auto-pack (relayed). */
/* 2026-07-28: Clear and Download Preview are BACK in the header. Hiding them
   left the only route to "start over" buried in the mobile overflow menu, and
   made the preview download unreachable on desktop entirely — it still worked,
   but nothing on screen could trigger it. Both are real actions users need. */
/* 2026-08-28: the GAP control is back on desktop.
   Hiding it left desktop users with no way to change the gap at all, while the
   mobile size panel still offers chips (2/4/6/8/12) plus a custom field - so the
   same builder gave one device a control and the other none. That is the same
   mistake the note above records for Clear and Preview, which were restored for
   exactly this reason.
   #build-sheet-btn stays hidden: the rail's "Pack the sheet" relays to it. */
#build-sheet-btn, #select-all-btn { display:none !important; }
#clear-btn, #preview-btn { display:inline-flex !important; align-items:center !important; gap:5px !important; }
.gs-floating-toolbar .gs-ft-divider, .gs-ft-toolbar .gs-ft-divider, .gs-canvas-toolbar .gs-ft-divider { display:none !important; }

/* -- Yellow checkout pill in the header ------------------------------------ */
.gs-hdr-checkout { display:inline-flex !important; align-items:center !important; gap:6px !important; background:#ffd400 !important; color:#151310 !important;
  border:2px solid #151310 !important; padding:6px 12px !important; font-family:var(--font-heading,'Syne',sans-serif) !important; font-weight:800 !important;
  font-size:12px !important; text-transform:uppercase !important; letter-spacing:.02em !important; text-decoration:none !important; margin-left:6px !important; white-space:nowrap !important; }
.gs-hdr-checkout:hover { background:#ffdf33 !important; }
.gs-hdr-checkout .material-symbols-rounded { font-size:16px !important; }

/* -- On-sheet "X% packed" fill chip ---------------------------------------- */
.gs-canvas-fillchip { position:absolute !important; top:12px !important; left:12px !important; z-index:20 !important;
  display:inline-flex !important; align-items:center !important; gap:7px !important; background:#151310 !important; color:#fff !important;
  font-family:var(--font-mono,'Space Mono',monospace) !important; font-size:11px !important; padding:5px 10px !important; border:2px solid #151310 !important;
  box-shadow:3px 3px 0 rgba(21,19,16,.25) !important; pointer-events:none !important; }
.gs-canvas-fillchip[hidden] { display:none !important; }
.gs-canvas-fillchip strong { font-weight:700 !important; color:#ffd400 !important; }
.gs-canvas-fillchip__dot { width:8px !important; height:8px !important; border-radius:50% !important; background:#1a8f4c !important; flex:0 0 8px !important; }

/* -- Show Library + Drafts in the rail (exact-match) ----------------------- */
#library-icon-btn, #drafts-icon-btn { display:flex !important; }

/* ── The gap control, restyled for v28 ────────────────────────────────────
   Its base rule is color: rgba(255,255,255,.5) — written for the old DARK
   toolbar. v28 made that bar paper (#f7f2e6), so simply un-hiding it would have
   put near-white text on a light ground. Ink on paper is 16.60:1.

   The input is given the same border and radius as the sibling buttons so the
   toolbar reads as one row of controls rather than a form dropped into it. */
.gs-floating-toolbar .gs-ft-gap-label {
  display: inline-flex !important; align-items: center; gap: 5px;
  font-family: var(--f-display); font-size: 11px !important; font-weight: 700;
  color: #151310 !important; padding: 0 4px; white-space: nowrap; cursor: default;
}
.gs-floating-toolbar .gs-ft-gap-input {
  width: 46px; padding: 4px 6px; font-family: var(--f-mono, 'Space Mono', monospace);
  font-size: 11px; font-variant-numeric: tabular-nums; text-align: center;
  color: #151310; background: #ffffff;
  border: 1.5px solid #151310; border-radius: 7px;
}
.gs-floating-toolbar .gs-ft-gap-input:focus-visible { outline: 2px solid #00a7e1; outline-offset: 1px; }
