/* ============================================================
   3D Merch Builder — v28 paper-light skin (override layer)
   Loads AFTER src/styles.css, which stays byte-faithful to the
   live builder. Paper stock UI, ink text, CMYK process accents,
   Syne/Space Grotesk/Space Mono. Pairs with the scene.js paper
   stage sweep (two flagged value edits).
   ============================================================ */

:root {
  --cyan: #00a7e1;
  --slate: #151310;
  --navy: #151310;            /* used as text-on-cyan → ink */
  --panel: #f7f2e6;
  --line: rgba(21, 19, 16, .18);
  --txt: #151310;
  --muted: #6f6759;
  --warn: #c25a1a;            /* darkened for light ground */
  --bad: #c22f2f;
}

html, body { background: #efe9db; }

/* ── Type: v28 stack ── */
.topbar .brand-name, .launch h2, .panel__head .panel__title, .lbl, .presets button,
.readout .val, .viewseg button, .payload__head b, .garment-chip,
.launch-btn, .btn { font-family: 'Syne', sans-serif !important; }
body, select, input, textarea, .hint, .zone-item, .price, .status p, .toast
  { font-family: 'Space Grotesk', system-ui, sans-serif; }
.price b, .readout .val { font-family: 'Space Mono', monospace !important; }

/* ── Chrome ── */
.topbar { background: linear-gradient(180deg, rgba(239, 233, 219, .95), rgba(239, 233, 219, 0)); }
/* v28 registration-square brand mark (matches site-v28 nav) */
.topbar .brand { gap: 8px; }
.topbar .brand .sq { display: flex; gap: 2px; margin-right: 2px; }
.topbar .brand .sq i { width: 6px; height: 15px; }
.topbar .brand .sq i:nth-child(1) { background: #00a7e1; }
.topbar .brand .sq i:nth-child(2) { background: #ec1e79; }
.topbar .brand .sq i:nth-child(3) { background: #ffd400; }
.topbar .brand-name b { color: #007bb0; }
.topnav a:hover { color: var(--txt); background: rgba(21, 19, 16, .07); }
.badge--p { background: #e6dfcd; color: #007bb0; }

.launch-btn {
  background: var(--cyan); color: #151310;
  border: 2px solid #151310; border-radius: 8px;
  box-shadow: 5px 5px 0 #151310;
}

/* ── Panel = paper card, ink border, hard shadow ── */
.panel {
  background: rgba(247, 242, 230, .95);
  border: 2px solid #151310;
  box-shadow: 8px 8px 0 rgba(21, 19, 16, .16);
  border-radius: 10px;
}
.garment-chip { background: rgba(21, 19, 16, .04); }
.garment-chip.on { background: rgba(0, 167, 225, .12); color: #007bb0; border-color: #007bb0; }
.garment-chip em { color: var(--muted); }
select, input[type=number], textarea { background: #efe9db; border-color: rgba(21, 19, 16, .3); }
.btn { background: var(--cyan); color: #151310; border: 2px solid #151310; border-radius: 7px; box-shadow: 3px 3px 0 #151310; }
.btn:disabled { box-shadow: none; }
.btn--ghost { background: transparent; color: var(--txt); border: 1.5px solid rgba(21, 19, 16, .35); box-shadow: none; }
.presets button { background: rgba(21, 19, 16, .04); }
.presets button.on { background: rgba(0, 167, 225, .12); border-color: #007bb0; color: #007bb0; }
.zone-item .side { background: rgba(21, 19, 16, .07); }
.zone-item.active { background: rgba(0, 167, 225, .1); }
.zone-item .dot { background: #ff5a1f; }
.hint b { color: #007bb0; }
.sw.active { border-color: #151310; }

/* checkerboards: slate → paper */
.thumb { background: repeating-conic-gradient(#d8d0bd 0 25%, #efe9db 0 50%) 0 0/10px 10px; }
.lib-item { background: repeating-conic-gradient(#d8d0bd 0 25%, #efe9db 0 50%) 0 0/8px 8px; }
/* pers-preview canvas carries an inline dark checkerboard — must out-rank it.
   Mid-tone checkers so BOTH white and black text previews stay visible. */
#pers-preview { background: repeating-conic-gradient(#9d9585 0 25%, #857d6d 0 50%) 0 0/12px 12px !important; border-color: rgba(21, 19, 16, .3) !important; }
.lib-item:hover { border-color: #007bb0; }

/* ── Floating widgets ── */
.toast { background: #151310; color: #efe9db; border: none; }
.viewseg { background: rgba(247, 242, 230, .95); border: 1.5px solid #151310; }
.viewseg button.on { background: rgba(0, 167, 225, .16); color: #007bb0; }
.pill { background: rgba(247, 242, 230, .95); border: 1.5px solid #151310; }
.pill b { color: #007bb0; }
.spinner { border-color: rgba(0, 167, 225, .25); border-top-color: var(--cyan); }

/* ── Payload (debug JSON) = ink block, mono paper text ── */
.payload { background: #151310; border-color: var(--cyan); }
.payload__head { background: #151310; }
.payload pre { color: #d9d2c0; }

/* ============================================================
   MOBILE SHELL (v28) — activated by body.is-mobile (set in src/mobile.js).
   Portrait → bottom-sheet drawer; landscape → left side-drawer.
   Always-on action bar (designs count + live price + Add to cart).
   New chrome is display:none by default and only appears once booted.
   ============================================================ */

/* New chrome hidden on desktop */
.mb-backdrop, .mb-bottombar, .mb-hint { display: none; }
.mb-backdrop[hidden], .mb-hint[hidden] { display: none !important; }

/* ── touch + scroll hardening (defeats iOS pull-to-refresh / body drag under the sheet) ── */
html.is-mobile-builder, body.is-mobile {
  position: fixed; inset: 0; width: 100%; height: 100%;
  overflow: hidden; overscroll-behavior: none;
}
body.is-mobile #stage { overscroll-behavior: contain; touch-action: none; }
body.is-mobile { --mb-bar-h: 60px; }

/* ── compact header + relocate floating widgets on mobile ── */
body.is-mobile .topbar { height: 48px; }
body.is-mobile .topbar .brand-name { font-size: 12px; }
body.is-mobile .pill { display: none; }
/* Front/Back segment → top-centre, clear of the drawer + action bar */
body.is-mobile .viewseg {
  top: calc(48px + env(safe-area-inset-top) + 8px); bottom: auto;
}

/* ── backdrop ── */
.mb-backdrop {
  position: fixed; inset: 0; z-index: 9010;
  background: rgba(21, 19, 16, .38); opacity: 0; transition: opacity .25s;
}
body.is-mobile .mb-backdrop { display: block; }
body.is-mobile .mb-backdrop[hidden] { display: none; }
.mb-backdrop.is-open { opacity: 1; }

/* ── always-on bottom action bar ── */
body.is-mobile.is-booted .mb-bottombar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 9020;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  background: rgba(247, 242, 230, .98);
  border-top: 2px solid #151310;
  box-shadow: 0 -6px 22px rgba(21, 19, 16, .14);
}
.mb-bb-designs {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 9px;
  background: #efe9db; border: 1.5px solid rgba(21, 19, 16, .3); border-radius: 9px;
  padding: 7px 11px; color: var(--txt); text-align: left; cursor: pointer;
  font-family: 'Space Grotesk', sans-serif;
}
.mb-bb-chev { flex: 0 0 auto; font-size: 13px; color: #007bb0; transition: transform .25s; }
/* chevron flips up→down when the drawer is open (panel precedes the bar in the DOM) */
body.is-mobile .panel:not(.collapsed) ~ .mb-bottombar .mb-bb-chev { transform: rotate(180deg); }
.mb-bb-stack { display: flex; flex-direction: column; min-width: 0; line-height: 1.18; }
.mb-bb-count { font-size: 11.5px; font-weight: 600; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mb-bb-price { font-family: 'Space Mono', monospace; font-size: 14px; font-weight: 700; color: #151310; }
.mb-bb-cart {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px;
  background: var(--cyan); color: #151310; border: 2px solid #151310; border-radius: 8px;
  box-shadow: 3px 3px 0 #151310; padding: 10px 15px; cursor: pointer;
  font-family: 'Syne', sans-serif; font-weight: 800; font-size: 13px;
}
.mb-bb-cart:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 #151310; }

/* ── gesture hint pill ── */
body.is-mobile .mb-hint {
  position: fixed; left: 50%; top: calc(48px + env(safe-area-inset-top) + 46px);
  transform: translate(-50%, -8px); z-index: 9030;
  display: flex; align-items: center; gap: 10px;
  background: #151310; color: #efe9db; border-radius: 99px;
  padding: 8px 10px 8px 16px; font: 500 12px/1 'Space Grotesk', sans-serif;
  opacity: 0; transition: opacity .25s, transform .25s; pointer-events: none;
}
body.is-mobile .mb-hint[hidden] { display: none; }
.mb-hint.is-in { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.mb-hint-x { background: rgba(255, 255, 255, .14); border: none; color: #efe9db; width: 22px; height: 22px; border-radius: 50%; cursor: pointer; font-size: 11px; line-height: 1; }

/* ── the #panel becomes a drawer on mobile; keep its body in flow so it slides as one piece ── */
body.is-mobile .panel .panel__body { display: block !important; }
body.is-mobile .panel__head { position: relative; padding-top: 16px; }
body.is-mobile .panel__head::before {
  content: ''; position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
  width: 38px; height: 4px; border-radius: 99px; background: rgba(21, 19, 16, .28);
}

/* PORTRAIT — bottom-sheet */
body.is-mobile:not(.is-landscape-mobile) .panel {
  position: fixed; left: 8px; right: 8px; top: auto;
  bottom: calc(var(--mb-bar-h) + env(safe-area-inset-bottom) + 6px);
  width: auto; max-width: none; height: min(66dvh, 580px);
  border-radius: 16px 16px 12px 12px; z-index: 9015;
  transform: translateY(0); transition: transform .32s cubic-bezier(.22, .61, .36, 1);
}
body.is-mobile:not(.is-landscape-mobile) .panel.collapsed {
  transform: translateY(calc(100% - 46px));   /* head peeks above the bar */
}
@keyframes mbNudge {
  0%, 100% { transform: translateY(calc(100% - 46px)); }
  42%      { transform: translateY(calc(100% - 78px)); }
  71%      { transform: translateY(calc(100% - 54px)); }
}
body.is-mobile:not(.is-landscape-mobile) .panel.collapsed.is-nudge { animation: mbNudge 1.1s ease 2; }

/* LANDSCAPE — left side-drawer + floating action cluster */
body.is-mobile.is-landscape-mobile .panel {
  position: fixed; left: 0; top: 0; bottom: 0; height: auto;
  width: 300px; max-width: 82vw; border-radius: 0 14px 14px 0; z-index: 9015;
  transform: translateX(0); transition: transform .3s cubic-bezier(.22, .61, .36, 1);
  box-shadow: 8px 0 30px rgba(21, 19, 16, .22);
}
body.is-mobile.is-landscape-mobile .panel.collapsed { transform: translateX(-100%); }
body.is-mobile.is-landscape-mobile .panel__head::before { display: none; }
body.is-mobile.is-landscape-mobile.is-booted .mb-bottombar {
  left: auto; right: 12px; bottom: 12px; width: auto;
  border: 2px solid #151310; border-radius: 12px;
  padding: 8px; box-shadow: 4px 4px 0 rgba(21, 19, 16, .18);
}
body.is-mobile.is-landscape-mobile .viewseg { top: calc(48px + 6px); }

/* Pinch on the shell must never zoom the page. The locked viewport covers Android,
   but iOS Safari ignores user-scalable=no — so suppress touch-zoom on the always-
   visible chrome directly (taps still fire; the drawer body keeps scroll; the 3D
   canvas #stage keeps its own touch-action:none + OrbitControls gestures). */
body.is-mobile .topbar,
body.is-mobile .mb-bottombar,
body.is-mobile .mb-bb-designs,
body.is-mobile .mb-bb-cart,
body.is-mobile .viewseg,
body.is-mobile .panel__head { touch-action: none; }

/* 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; } }


/* ══════════════════════════════════════════════════════════════════════════
   IA-2 — site chrome on the merch builder
   ══════════════════════════════════════════════════════════════════════════

   /merch-builder/ loads NO site-v28 CSS, only this skin. It could not simply be
   added: site-v28 carries element-level rules for * html body a button input
   select img and h1-h3, including a body background and font-family, so
   importing it would restyle the whole 3D tool rather than just adding a header.

   So the header and footer rules are ported here instead — copied from
   site-v28/css/layout.css, which stays the source. If that file's chrome
   changes, re-port; the two are not automatically in sync and pretending
   otherwise is how they drift.

   The tokens below are the nine those rules reference. The merch skin defines
   none of them except --cyan (same value), and references none of the others
   anywhere, so declaring them cannot change how the tool renders.
   ────────────────────────────────────────────────────────────────────────── */

:root {
  --ink:        #151310;
  --paper:      #efe9db;
  --paper-2:    #e6dfcd;
  --mag:        #ec1e79;
  --yel:        #ffd400;
  --maxw:       1240px;
  --ease:       cubic-bezier(0.22, 1, 0.36, 1);
  --f-display:  "Syne", sans-serif;
}

/*
 * THE SHELL SCROLLS ON DESKTOP; THE MOBILE APP STAYS LOCKED.
 *
 * The tool was html,body{height:100%;overflow:hidden} with #stage{inset:0} — a
 * full-viewport app, which is why it could never have a footer: there was
 * nothing to scroll to. The page is now header / .mb-app / footer in normal
 * flow.
 *
 * .mb-app is position:relative and that is the load-bearing part. Every piece
 * of tool furniture (.topbar, .launch, .status, .toast, .panel, .viewseg,
 * .pill, .payload) is position:absolute and was anchoring to the viewport.
 * Giving them a positioned ancestor re-anchors the lot in one move, with no
 * change to any of their own rules.
 *
 * body.is-mobile keeps position:fixed;inset:0 further down this file, so the
 * phone shell is untouched and still behaves as an app. The consequence, stated
 * rather than hidden: on mobile the footer is present in the DOM (so crawlers
 * and assistive tech see it) but is not reachable by scrolling while the app
 * shell is active. Desktop gets the full fix.
 */
html, body { height: auto; overflow: visible; }
body { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }

.mb-app {
  position: relative;
  flex: 1 1 auto;
  /* A floor, so the 3D stage keeps a usable height on short windows rather than
     collapsing to whatever is left over. */
  min-height: 560px;
  height: calc(100dvh - 52px);
}
.mb-app #stage { position: absolute; inset: 0; }

/* The visually-hidden pattern the gang builder already uses for its real H1. */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* The wordmark in the tool's own top bar. Was an <h1>, which made the brand
   lockup and the page heading the same element (IA-2). Same look, no outline. */
.topbar .brand-name {
  font-size: 14px; font-weight: 800; letter-spacing: .04em; margin: 0;
  text-transform: uppercase; font-family: 'Syne', sans-serif; color: var(--txt);
}
.topbar .brand-name b { color: #007bb0; }

/* ── ported verbatim from site-v28/css/layout.css ────────────────────────── */
.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;}
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;}
.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;}
.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 .links a.active::after {transform: scaleX(1); transform-origin: left;}
.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);}
.nav .burger {display: none; flex-direction: column; gap: 4px;}
.nav .burger i {width: 22px; height: 2.5px; background: var(--ink);}
@media (max-width: 1100px) {
  .nav .links a:not(.cta) {display: none;}
  .nav .burger {display: flex;}
  .nav {padding: 14px 20px;}
  .nav {justify-content: flex-start; gap: 10px;}
  .nav .brand {margin-right: auto;}
}
footer {background: var(--ink); color: var(--paper); padding: 64px 0 34px;}
.fbrand .brand {color: var(--paper); margin-bottom: 14px;}
footer .lh::after {background: var(--yel);}
body.admin-bar header.site-header {top: 32px;}
body.admin-bar > header {top: 32px;}
@media screen and (max-width: 782px) {
  body.admin-bar > header {top: 46px;}
}
@media screen and (max-width: 600px) {
  body.admin-bar > header {top: 0;}
}
.nav .cta {white-space: nowrap;}
.nav .burger {background: none; border: 0; padding: 6px; cursor: pointer;}
@media (max-width: 1100px) {
  .nav {position: relative;}
  .nav .cta {padding: 9px 14px; font-size: 13px; box-shadow: 3px 3px 0 var(--cyan);}
  .nav .burger {display: flex;}
  header.nav-open .links {display: flex; flex-direction: column; align-items: stretch; gap: 0; position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 950; background: var(--paper); border: 2.5px solid var(--ink); box-shadow: 8px 8px 0 var(--ink); padding: 10px;}
  header.nav-open .links a:not(.cta) {display: flex; align-items: center; gap: 12px; font-family: var(--f-display); font-weight: 700; text-transform: uppercase; font-size: 17px; letter-spacing: -0.01em; line-height: 1; padding: 13px 12px; border-bottom: 1.5px solid var(--paper-2); transition: background 0.15s var(--ease), padding-left 0.15s var(--ease);}
  header.nav-open .links a:not(.cta)::before {content: ""; width: 11px; height: 11px; flex: 0 0 11px; border: 1.5px solid var(--ink); background: transparent;}
  header.nav-open .links a:not(.cta):nth-of-type(4n+1)::before {background: var(--cyan);}
  header.nav-open .links a:not(.cta):nth-of-type(4n+2)::before {background: var(--mag);}
  header.nav-open .links a:not(.cta):nth-of-type(4n+3)::before {background: var(--yel);}
  header.nav-open .links a:not(.cta):nth-of-type(4n+4)::before {background: var(--ink);}
  header.nav-open .links a:not(.cta):last-of-type {border-bottom: 0;}
  header.nav-open .links a:not(.cta):hover, header.nav-open .links a:not(.cta):focus-visible {background: var(--ink); color: var(--paper); padding-left: 18px;}
  header.nav-open .links .cta {margin: 10px 2px 2px; text-align: center; justify-content: center; padding: 14px 16px; font-size: 14px; box-shadow: 4px 4px 0 var(--ink);}
}
.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: 0.66s;}
.brand .sq i:nth-child(2) {animation-delay: 0.77s;}
.brand .sq i:nth-child(3) {animation-delay: 0.88s;}
@media (prefers-reduced-motion: reduce) {
  .brand .sq i {animation: none;}
}
@media (max-width: 480px) {
  header:not(.nav-open) .nav .links {display: none;}
}
/* ── end ported chrome ──────────────────────────────────────────────────── */

/*
 * The persistent price readout.
 *
 * Merch used to show no price anywhere before "Add to cart" — the figure existed
 * but only inside a collapsible panel group most people never opened. Wave 2
 * ranked that the site's single biggest friction, on the one product a customer
 * can buy without owning a press.
 *
 * It sits in the top bar because that is the one piece of tool chrome that is
 * always visible, at every step, on every garment. pointer-events stay off so it
 * cannot steal a drag meant for the model.
 */
.price-live {
  margin-left: auto; display: inline-flex; align-items: baseline; gap: 7px;
  padding: 5px 12px; border: 2px solid var(--ink); border-radius: 999px;
  background: var(--paper); pointer-events: none; white-space: nowrap;
}
.price-live__lbl {
  font-family: 'Space Mono', monospace; font-size: 9px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: #6b6558;
}
.price-live__val {
  font-family: 'Space Mono', monospace; font-size: 15px; font-weight: 800;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
/* The topnav already claimed margin-left:auto; with the price before it, the
   price takes that role and the nav simply follows. */
.topbar .topnav { margin-left: 10px; }

/* On a phone the bottom action bar already carries the running total, so a
   second copy in a 48px-tall bar would only crowd the wordmark out. */
body.is-mobile .price-live { display: none; }


/* ══════════════════════════════════════════════════════════════════════════
   IA-2 follow-up — the FOOTER's own rules
   ══════════════════════════════════════════════════════════════════════════

   The first port took every selector mentioning `header` or `footer` and missed
   the footer's internals entirely, because they are named `.fgrid` `.fcol`
   `.fbrand` `.fsocial` `.colophon` — none of which contain the word "footer".

   The result looked deployable and was not: links rendered in WordPress default
   blue and underlined, the <h5> column headings came out near-black ON a
   near-black background (invisible), and .fgrid fell back to display:block so
   the four columns stacked. A structural check said "footer present, 18 links"
   and passed. Only reading the computed styles showed it.

   Ported complete this time, including the eight @keyframes the social icons
   animate with, and the two extra tokens those rules reference. The merch skin
   references neither, so declaring them changes nothing in the tool.
   ────────────────────────────────────────────────────────────────────────── */

:root {
  --f-mono: "Space Mono", monospace;
  --orange: #ff5a1f;
}

footer { background: var(--ink); color: var(--paper); padding: 64px 0 34px; }
.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-bottom: 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; }
/* social icon row (ACF-driven; only set networks render) — v28 CMYK motion */
.fsocial { display: flex; gap: 10px; margin-top: 18px; }
.fsocial a { position: relative; width: 38px; height: 38px; padding: 0; display: grid; place-items: center; border: 2px solid rgba(239, 233, 219, 0.28); color: var(--paper); transition: background .15s ease, color .15s ease, border-color .15s ease; }
.fsocial a svg { display: block; width: 19px; height: 19px; fill: currentColor; }
.fsocial__gly, .fsocial__layer { display: grid; place-items: center; }
.fsocial__layer { position: absolute; inset: 0; }
.fsocial__layer--c, .fsocial__layer--m { opacity: 0; }
.fsocial a:hover { color: var(--ink); }
.fsocial a:nth-child(1):hover { background: var(--cyan); border-color: var(--cyan); }
.fsocial a:nth-child(2):hover { background: var(--mag); border-color: var(--mag); }
.fsocial a:nth-child(3):hover { background: var(--yel); border-color: var(--yel); }
.fsocial a:nth-child(4):hover { background: var(--orange); border-color: var(--orange); }

/* one signature motion per network, always gently looping (staggered) */
@keyframes fsIgPress { 0%,72%,100% { transform: scale(1); } 78% { transform: scale(.82); } 86% { transform: scale(1.06); } 92% { transform: scale(1); } }
@keyframes fsIgRing  { 0%,72% { transform: scale(.55); opacity: 0; } 79% { opacity: .85; } 100% { transform: scale(1.7); opacity: 0; } }
@keyframes fsTtBase  { 0%,60%,100% { transform: translate(0,0); } 70% { transform: translate(1px,-1px); } 82% { transform: translate(-1px,1px); } }
@keyframes fsTtC { 0%,60%,100% { transform: translate(0,0); opacity: 0; } 66% { opacity: .6; } 72% { transform: translate(-1.5px,.5px); } 80% { transform: translate(1px,-.5px); } 90% { transform: translate(-.5px,0); opacity: .3; } }
@keyframes fsTtM { 0%,60%,100% { transform: translate(0,0); opacity: 0; } 66% { opacity: .6; } 72% { transform: translate(1.5px,-.5px); } 80% { transform: translate(-1px,.5px); } 90% { transform: translate(.5px,0); opacity: .3; } }
@keyframes fsFbPop { 0%,60%,100% { transform: scale(1); } 70% { transform: scale(.8); } 80% { transform: scale(1.16); } 88% { transform: scale(.96); } 94% { transform: scale(1.02); } }
@keyframes fsYtPulse { 0%,55%,100% { transform: scale(1); } 72% { transform: scale(1.18); } 85% { transform: scale(.98); } }
@keyframes fsYtScan { 0%,55% { transform: translateY(-120%); opacity: 0; } 60% { opacity: .5; } 78% { transform: translateY(120%); opacity: .5; } 80%,100% { opacity: 0; } }

.fsocial__link--ig .fsocial__gly { animation: fsIgPress 5s ease-in-out infinite; }
.fsocial__link--ig::after { content: ""; position: absolute; inset: 5px; border: 2px solid var(--cyan); opacity: 0; pointer-events: none; animation: fsIgRing 5s ease-out infinite; }
.fsocial__link--tt .fsocial__layer--base { animation: fsTtBase 5s .4s ease infinite; }
.fsocial__link--tt .fsocial__layer--c { color: var(--cyan); mix-blend-mode: screen; animation: fsTtC 5s .4s ease infinite; }
.fsocial__link--tt .fsocial__layer--m { color: var(--mag); mix-blend-mode: screen; animation: fsTtM 5s .4s ease infinite; }
.fsocial__link--fb .fsocial__gly { animation: fsFbPop 5s .8s ease-in-out infinite; }
.fsocial__link--yt .fsocial__gly { animation: fsYtPulse 5s 1.2s ease-in-out infinite; }
.fsocial__link--yt::before { content: ""; position: absolute; left: 4px; right: 4px; top: 0; height: 34%; background: linear-gradient(var(--orange), transparent); opacity: 0; pointer-events: none; animation: fsYtScan 5s 1.2s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .fsocial__link *, .fsocial__link::before, .fsocial__link::after { animation: none !important; }
  .fsocial__link--yt::before, .fsocial__link--ig::after { opacity: 0 !important; }
}
.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);
}
footer .lh::after { background: var(--yel); }
@media (max-width: 820px) { .fgrid { grid-template-columns: 1fr 1fr; } }

/*
 * Chrome links are not underlined.
 *
 * This page carries an inline <style> with a bare `a { text-decoration:
 * underline }`, which sits later in the cascade than GeneratePress's
 * `a { text-decoration: none }` and therefore wins. On the pages that load
 * site-v28 the chrome never sees that, so the header and footer look right
 * everywhere else and were underlined only here.
 *
 * Scoped to header/footer on purpose: specificity (0,0,2) beats the bare `a`
 * whatever the source order, and the tool's own links are left alone rather
 * than being restyled by a global override.
 */
header a, footer a { color: inherit; text-decoration: none; }
/*
 * ...and something for those anchors to inherit FROM.
 *
 * On every other page base.css supplies `a { color: inherit }` plus
 * `body { color: var(--ink) }`. This page has neither, so the first version of
 * this rule fixed the underline and left the header brand and links rendering
 * in WordPress blue (rgb(30,115,190)) — legible, entirely wrong, and something
 * a structural check cannot see.
 *
 * footer already declares its own colour, and .fgrid a sets #e6dfcd explicitly,
 * so only the header needs a ground colour here.
 */
header { color: var(--ink); }

/* D1 — the shipping line beside the running total. Quiet: it qualifies the
   price, it is not a second headline. Hidden on a phone, where the bottom
   action bar already carries the total and the bar is only 48px tall. */
.price-live__ship {
  font-family: 'Space Mono', monospace; font-size: 9px; font-weight: 600;
  letter-spacing: .02em; color: #6b6558; white-space: nowrap; margin-left: 2px;
}
body.is-mobile .price-live__ship { display: none; }

/* D5 — the cart-lock notice. Deliberately unlike the shipping line beside it:
   larger, darker and NOT hidden on mobile. Shipping is information; this is the
   reason the next click will fail, and a phone customer needs it most. #8a3b00
   on paper is 6.41:1. The element is empty unless the server reports a lock, so
   it costs no space in the normal case. */
.price-live__lock {
  font-family: 'Space Mono', monospace; font-size: 11px; font-weight: 700;
  letter-spacing: .01em; color: #8a3b00; margin-left: 2px;
  white-space: normal; max-width: 34ch;
}
.price-live__lock:empty { display: none; }

/* ── D6 · the placement fee, on the chip that causes it ──────────────────────
   The zone picker is where decoration cost is actually decided — front + back
   on a $14.95 tee is $20.00 of decoration, more than the garment — and it
   showed nothing until the total.

   Both states show the SAME string; only weight and colour differ, so the list
   never reads as two different prices. Contrast on --panel #f7f2e6:
   muted 5.00:1, ink 16.60:1 — both AA. */
.zone-item .zone-fee {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}
.zone-item .zone-fee.is-charged { color: #151310; font-weight: 700; }
/* The rationale sits under the total, quiet. #6f6759 on --panel is 5.00:1 (AA).
   Collapsed entirely when empty, so a garment with no art loses no space. */
.deco-why { margin: 6px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--muted); max-width: 46ch; }
.deco-why:empty { display: none; }

/* ─── TOPBAR IS EMPTY ON MOBILE — 2026-09-11 ──────────────────────────────
   The builder wordmark was removed (it duplicated the site header's own), and
   .price-live is already display:none on mobile — so on a phone .topbar has no
   content left and would render as a dead 48px gradient strip over the canvas.
   Desktop keeps it: that is where the live total shows. ── */
body.is-mobile .topbar { display: none; }
