/* ◈ GAME LAYER — boot splash · desktop HUD · profile console · 5-tab phone bar
   Palette and type are the site's own tokens (--gd-purple, --gd-mono, --glass-*).
   Nothing here owns state: the HUD mirrors #cartCount and /api/me; the splash paints over
   the page and then removes itself from the DOM. */

/* ── boot splash ─────────────────────────────────────────────────────────── */
html.gd-booting { overflow: hidden; }
#gdBoot {
  position: fixed; inset: 0; z-index: 99999; background: #05060f; color: #c9b6ff;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-family: var(--game-mono); cursor: pointer;
  opacity: 1; transition: opacity .45s var(--ease-out-expo);
  -webkit-user-select: none; user-select: none;
}
#gdBoot.gd-boot-out { opacity: 0; pointer-events: none; }
#gdBoot .gd-boot-ascii { position: absolute; inset: 0; display: block; animation: gd-boot-in 1.1s ease both; }
#gdBoot .gd-boot-word, #gdBoot .gd-boot-sub, #gdBoot .gd-boot-hint { position: relative; z-index: 1; }
#gdBoot .gd-boot-hint { position: absolute; }
#gdBoot .gd-boot-word {
  /* the site's own wordmark, measured live 2026-09-02: Inter 700, uppercase, -0.01em, white */
  font-family: var(--game-sans); font-weight: 700; text-transform: uppercase;
  margin-top: 22px; font-size: clamp(var(--t-h1), 5.2vw, var(--t-d2)); letter-spacing: -0.01em; line-height: 1.06;
  color: #fff; opacity: 0; transform: translateY(6px); animation: gd-boot-word .8s ease .6s both;
  text-shadow: 0 0 18px var(--g-lit-7, rgba(139, 92, 246, .7));
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
#gdBoot .gd-boot-word b { color: inherit; font-weight: inherit; }   /* all white, like the header's wordmark */
#gdBoot .gd-boot-sub {
  /* the header's own info line, measured live 2026-09-02: Inter 400, 14px, 0.16em, lavender */
  font-family: var(--game-sans); font-weight: 400;
  margin-top: 10px; font-size: var(--t-data); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--g-hi-3, #c2a6ff); opacity: 0; animation: gd-boot-word .6s ease 1.25s both;
}
#gdBoot .gd-boot-hint {
  font-family: var(--game-sans);
  position: absolute; bottom: calc(18px + env(safe-area-inset-bottom, 0px)); font-size: var(--t-label); letter-spacing: .16em;
  text-transform: uppercase; color: #5c5878; opacity: 0; animation: gd-boot-blink 1.4s ease 1.5s infinite;
}
@keyframes gd-boot-in   { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
@keyframes gd-boot-word { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes gd-boot-blink { 0%, 100% { opacity: 0; } 50% { opacity: .9; } }
@media (prefers-reduced-motion: reduce) {
  #gdBoot .gd-boot-ascii, #gdBoot .gd-boot-word, #gdBoot .gd-boot-sub { animation: none; opacity: 1; transform: none; }
  #gdBoot .gd-boot-hint { animation: none; opacity: .9; }
}

/* ── desktop HUD (the phone has the tab bar; the desktop gets a mini status bar) ── */
/* ── THE LAYER'S PALETTE, AS TOKENS ──────────────────────────────────────────────────────
   Operator 2026-09-03, of the other storefront: "the new dark mode in some screens is a bit
   extreme and the menu bar is a bit way too off from the original scheme ... modify the entire
   site at once but keep it more moderate."
   Measured there: the page is #efefef with #111 ink, and this layer sat on it as a near-black
   LAVENDER glass — rail rgba(20,15,36,.58), tab text #9d8fb8, console ink #e9e9f4. Correct for
   this dark storefront, a foreign object on that light institutional one.
   Every value below is the literal that was already here, so THIS site renders byte-identically.
   The other site re-themes by setting the tokens — one block, no fork, structure untouched. */
:root {
  --g-surface: #0b0c1a;
  --g-surface-2: rgba(8, 9, 18, .96);
  --g-surface-3: rgba(8, 9, 18, .97);
  --g-surface-4: rgba(8, 9, 18, .94);
  --g-glass: rgba(20, 15, 36, .58);
  --g-scrim: rgba(5, 6, 15, .55);
  --g-scrim-2: rgba(5, 6, 15, .62);
  --g-scrim-3: rgba(5, 6, 15, .78);
  --g-raise: rgba(255, 255, 255, .03);
  --g-raise-2: rgba(255, 255, 255, .04);
  --g-raise-3: rgba(255, 255, 255, .05);
  --g-ink: #e9e9f4;
  --g-ink-2: #c9c4dc;
  --g-ink-3: #a8a3c6;
  --g-ink-4: #8b86a8;
  --g-ink-5: #8a85a6;
  --g-ink-6: #6f6a8a;
  --g-ink-7: #9d8fb8;
  --g-ink-8: #cfc6ea;
  --g-line: rgba(194, 163, 255, .16);
  --g-line-2: rgba(194, 163, 255, .18);
  --g-line-3: rgba(194, 163, 255, .35);
  --g-line-4: rgba(194, 163, 255, .4);
  --g-line-5: rgba(194, 163, 255, .5);
  --g-lip: rgba(255, 255, 255, .055);
  --g-lip-2: rgba(255, 255, 255, .08);
  --g-lip-3: rgba(255, 255, 255, .12);
  --g-hi: #ccb2ff;
  --g-hi-2: #b48cff;
  --g-hi-3: #c2a6ff;

  /* the accent family: the flat colour, its alpha ramp, and the LIT state on the
     bar and the rail — the one the operator called "way too off from the original scheme". */
  --g-accent: #6600cc;
  --g-accent-06: rgba(102, 0, 204, .06);
  --g-accent-08: rgba(102, 0, 204, .08);
  --g-accent-1: rgba(102, 0, 204, .1);
  --g-accent-12: rgba(102, 0, 204, .12);
  --g-accent-15: rgba(102, 0, 204, .15);
  --g-accent-16: rgba(102, 0, 204, .16);
  --g-accent-18: rgba(102, 0, 204, .18);
  --g-accent-2: rgba(102, 0, 204, .2);
  --g-accent-22: rgba(102, 0, 204, .22);
  --g-accent-25: rgba(102, 0, 204, .25);
  --g-accent-3: rgba(102, 0, 204, .3);
  --g-accent-35: rgba(102, 0, 204, .35);
  --g-accent-4: rgba(102, 0, 204, .4);
  --g-accent-45: rgba(102, 0, 204, .45);
  --g-accent-5: rgba(102, 0, 204, .5);
  --g-accent-6: rgba(102, 0, 204, .6);
  --g-lit-18: rgba(139, 92, 246, .18);
  --g-lit-22: rgba(139, 92, 246, .22);
  --g-lit-30: rgba(139, 92, 246, .30);
  --g-lit-5: rgba(139, 92, 246, .5);
  --g-lit-7: rgba(139, 92, 246, .7);
}

/* ── THE GAME LAYER OWNS ITS OWN TYPE AND ITS OWN BOX MODEL ────────────────────────────
   Measured 2026-09-03 across three pages: the SAME shared components resolved to different
   typefaces (home '"JetBrains Mono", ui-monospace…', generated pages the two-item fallback)
   and different sizes (the rail avatar 26px on one page, 28px on another — no border-box
   reset there, so its 1px border was added OUTSIDE the 26). A shared component that inherits
   its box model and its typeface from whatever page it lands on is not shared.
   These are DEFAULTS: a page that declares its own tokens still wins. */
:root {
  /* PRIVATE TO THE LAYER, deliberately not --gd-sans / --gd-mono. Those are the PAGE's tokens,
     and every page declares its own slightly different list, so the shared chrome inherited a
     different family list on the home page than on a generated one — the same face, a different
     stack, and a real risk of a different face the day one page's list changes. The layer's own
     chrome uses the layer's own type. Colour still themes from the site (--glass-*, --gd-purple):
     a storefront should be able to recolour the layer, not restyle its type out from under it. */
  --game-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --game-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* THE LAYER'S RADIUS TOKENS WERE USED AND NEVER DEFINED IN THIS TREE (2026-09-23).
     33 declarations in this file resolve var(--g-r-ctl / -card / -panel); nothing in
     geneticdesigner/ declares them, so every one fell back to the initial value and the shared
     chrome drew square where the storefront drew rounded. Canon scale, same as the page tokens
     and the same as SBI: WEB_DESIGN_CANON.md §3. */
  --g-r-ctl: 10px;
  --g-r-card: 14px;
  --g-r-panel: 18px;

  /* ── THE CANON'S TYPE SCALE, MOTION AND ELEVATION ────────────────────────────────────────
     ~/canonical/empire/brand/WEB_DESIGN_CANON.md §4, §8 and §0.5. Declared HERE because this is
     the one stylesheet every page of this site loads — index, community, grow, terms, privacy,
     disclosure and all 478 strain pages — measured, not assumed. The same block went into SBI's
     game/game.css in the same pass, which is the canon's own law at the top of that file: when
     it changes, both sites change together.

     Measured on this tree before the change: index.html declared TWENTY distinct font sizes
     (8.5 through 44, six of them half-pixels), strain-profile.css seventeen, and of 83
     transitions across the three sheets EIGHTY ran on the browser's default `ease` — 44 naming
     it and 36 naming nothing at all. */
  --t-label: 12px;   /* eyebrow and label — UPPERCASE, tracking .08em, and nothing else */
  --t-data: 13.5px;  /* secondary: captions, citations, dense tabular data */
  --t-body: 15px;    /* running body */
  --t-lead: 17px;    /* a card's name, a record's name */
  --t-h3: 20px;
  --t-h2: 24px;
  --t-h1: 32px;
  --t-d1: 36px;      /* ornament, not type: an avatar initial, an unlock glyph */
  --t-d2: 54px;

  --measure: 1152px;      /* GGG .ggg-container / max-w-6xl */
  --measure-wide: 1040px; /* GGG .kit-wide */
  --measure-text: 720px;  /* GGG .kit-narrow */
  --gutter: 24px;
  --gutter-sm: 16px;

  --ease-out-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --dur: 220ms;

  /* ambient light plus key light — what stops a card reading as a sticker. This site's ground is
     dark, so the shadows are keyed to black rather than to SBI's ink. */
  --shadow-sm: 0 1px 2px -1px rgba(0,0,0,.34), 0 1px 3px -1px rgba(0,0,0,.24);
  --shadow-md: 0 4px 12px -4px rgba(0,0,0,.40), 0 2px 6px -3px rgba(0,0,0,.28);
  --shadow-lg: 0 18px 40px -20px rgba(0,0,0,.58), 0 6px 16px -10px rgba(0,0,0,.36);
  --shadow-xl: 0 36px 70px -30px rgba(0,0,0,.70), 0 12px 28px -16px rgba(0,0,0,.44);
}
@media (max-width: 640px) { :root { --gutter: 16px; } }

/* The finish GGG applies once, globally. Guarded motion, or invisible-until-absent. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }
h1, h2, h3, .text-balance { text-wrap: balance; }
p { text-wrap: pretty; }
.tnum { font-variant-numeric: tabular-nums; }
/* A <button> does not inherit font-family or line-height from its page: the UA resets both.
   Left to the page, the same bar was Inter on one and Arial on another, and the rail stood
   383px tall on two pages and 381px on a third. A shared component sets its own. */
.gd-tabbar { font-family: var(--game-sans); line-height: 1.3; }
.gd-tabbar .gd-tab, #gdHud, #gdHud .gd-hud-btn { font-family: inherit; line-height: 1.3; }
#gdHud { font-family: var(--game-mono); }
/* TYPE AT EVERY WIDTH, LAYOUT PER WIDTH. These lived only inside the media queries, so at the
   width where a control is hidden it fell back to the PAGE's `button {}` rule — 11px with 2px
   tracking on one storefront page, the UA's 13.3px on another. Hidden is not "does not matter":
   it is the state nobody looks at, which is where drift starts. */
.gd-tabbar .gd-tab { font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase; color: var(--g-ink-7, #9d8fb8); }
#gdHud .gd-hud-btn { font-size: var(--t-label); letter-spacing: .1em; text-transform: uppercase; color: var(--g-ink-8, #cfc6ea); }
/* AND THE LAYER'S BUTTONS RESIST THE PAGE'S OWN `button {}` RULE. Measured 2026-09-03 on
   seedbankinternational.com/breeders.html, which styles every button on the page:
   `button{margin-top:16px;width:100%;padding:13px;font-size: var(--t-label);letter-spacing:2px}`. The
   shared bar inherited the 16px top margin — 82px tall there, 66px everywhere else. Only the
   properties an unscoped element rule can INJECT are reset; everything the layer actually
   styles is left to the layer's own rules below. */
#gdHud .gd-hud-btn, .gd-tabbar .gd-tab, #feedConsole button, #profileConsole button,
.gd-notes button, .fx-unlock button {
  margin: 0; width: auto; min-width: 0; box-shadow: none;
}

#gdHud, #gdHud *, .gd-tabbar, .gd-tabbar *, #feedConsole, #feedConsole *,
#profileConsole, #profileConsole *, .fx-toasts, .fx-toasts *, .fx-unlock, .fx-unlock *,
.gd-notes, .gd-notes * { box-sizing: border-box; }

/* ── A KEYBOARD USER CAN ALWAYS SEE WHERE THEY ARE ───────────────────────────────────────
   Measured 2026-09-03 by tabbing 24 controls on each site: the other storefront was clean, this
   one had TWO of its own search boxes — the grow-shop search and the strain finder on the hero —
   reachable with no visible focus at all. Both carried an inline `outline:none` with nothing put
   in its place, and there are eight more inline `outline:none` inputs behind them, so patching
   the two would have left the class alive.
   :focus-visible, so a MOUSE click still shows nothing; only keyboard focus draws the ring.
   !important because the suppressions are inline styles, and :where() so this adds no specificity
   of its own — any deliberate, visible focus style a component defines still wins the look. */
:where(a[href], button, input, select, textarea, summary, [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--sbi-accent, #c2a3ff) !important;
  outline-offset: 2px !important;
  border-radius: var(--g-r-ctl);
}

#gdHud { display: none; }
@media (min-width: 701px) {
  #gdHud {
    display: flex; align-items: stretch; gap: 0;
    position: fixed; right: 16px; bottom: 16px; z-index: 1400;
    background: var(--glass-bg, var(--g-glass, rgba(20, 15, 36, .58)));
    -webkit-backdrop-filter: var(--glass-blur, blur(18px)); backdrop-filter: var(--glass-blur, blur(18px));
    border: 1px solid var(--glass-edge, var(--g-line, rgba(194, 163, 255, .16)));
    box-shadow: inset 0 1px 0 var(--glass-lip, var(--g-lip, rgba(255, 255, 255, .055))), 0 8px 30px rgba(0, 0, 0, .35);
    border-radius: var(--g-r-panel); padding: 4px; font-family: var(--game-mono);
    color: var(--g-ink-8, #cfc6ea); font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase;
  }
  #gdHud .gd-hud-btn {
    appearance: none; background: none; border: 0; color: inherit; font: inherit; letter-spacing: inherit;
    text-transform: inherit; cursor: pointer; display: flex; align-items: center; gap: 8px;
    padding: 7px 11px; border-radius: var(--g-r-card); min-height: 40px; transition: background var(--dur) var(--ease-out-expo), color var(--dur) var(--ease-out-expo);
  }
  #gdHud .gd-hud-btn:hover, #gdHud .gd-hud-btn:focus-visible { background: var(--g-lit-22, rgba(139, 92, 246, .22)); color: #fff; }
  #gdHud .gd-hud-btn[aria-current="true"] { background: var(--g-lit-30, rgba(139, 92, 246, .30)); color: #fff; }
  #gdHud .gd-hud-btn svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
  #gdHud .gd-hud-sep { width: 1px; margin: 8px 2px; background: var(--g-line-2, rgba(194, 163, 255, .18)); }
  #gdHud .gd-hud-avatar {
    width: 26px; height: 26px; border-radius: 50%; background: var(--g-accent-35, rgba(102, 0, 204, .35)); border: 1px solid var(--g-line-3, rgba(194, 163, 255, .35));
    display: grid; place-items: center; overflow: hidden; font-size: var(--t-label); color: #fff; flex: none;
  }
  #gdHud .gd-hud-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
  #gdHud .gd-hud-name { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
  #gdHud .gd-hud-name small { font-size: var(--t-label); color: var(--g-ink-7, #9d8fb8); letter-spacing: .14em; }
  #gdHud .gd-hud-bar { width: 64px; height: 3px; background: var(--g-lip-2, rgba(255, 255, 255, .08)); border-radius: var(--g-r-ctl); overflow: hidden; margin-top: 3px; }
  #gdHud .gd-hud-bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--g-accent, #6600cc), var(--g-hi-2, #b48cff)); transition: width .6s var(--ease-out-expo); }
  #gdHud .gd-hud-n {
    min-width: 17px; height: 17px; padding: 0 5px; border-radius: var(--g-r-ctl); background: var(--gd-purple, var(--g-accent, #6600cc)); color: #fff;
    font-size: var(--t-label); line-height: 17px; text-align: center; font-variant-numeric: tabular-nums;
  }
  #gdHud .gd-hud-n[hidden] { display: none; }
  #gdHud .gd-hud-n.is-live { background: #2f9a5a; }
}
@media (min-width: 701px) and (prefers-reduced-motion: reduce) { #gdHud .gd-hud-btn, #gdHud .gd-hud-bar i { transition: none; } }
@media (min-width: 701px) { .gd-tabbar { display: none; } }
@media (prefers-reduced-motion: reduce) { .gd-tabbar .gd-tab { transition: none; } }

/* ── phone tab bar ────────────────────────────────────────────────────────────────────
   THE WHOLE BAR LIVES HERE, not in one page's <style>. Measured 2026-09-03 at 390px:
   the home page had a fixed glass bar at the bottom of the SCREEN, and every one of the
   483 generated pages had `position: static; display: block` — the same markup, unstyled,
   parked 7,027px down at the bottom of the DOCUMENT. The bar was never on those pages'
   screens at all. It looked wired because the markup was there and the icons drew.
   The cause: hud.js and the injector are shared, this stylesheet is shared, and the CSS
   that turns the markup into a bar was page-local. Now it is not.

   NO PINNED COLUMN COUNT either: it was repeat(5) here and repeat(4) in the page, so
   adding a destination silently wrapped Profile onto a second row. Column flow makes the
   bar hold whatever it is given, at any count. */
@media (max-width: 700px) {
  nav.gd-tabbar[role="navigation"], .gd-tabbar {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; grid-template-columns: none;
    position: fixed; left: 8px; right: 8px; bottom: 8px;
    /* ABOVE the panels, never under them: the bar is persistent navigation, and the tab that
       lights up to show which surface is open is meaningless if that surface covers it. */
    z-index: 1400;
    border-radius: var(--g-r-panel); padding: 6px 4px;
    padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px));
    background: var(--glass-bg, var(--g-glass, rgba(20, 15, 36, .58)));
    -webkit-backdrop-filter: var(--glass-blur, blur(18px) saturate(132%));
    backdrop-filter: var(--glass-blur, blur(18px) saturate(132%));
    border: 1px solid var(--glass-edge, var(--g-line, rgba(194, 163, 255, .16)));
    box-shadow: inset 0 1px 0 var(--glass-lip, var(--g-lip, rgba(255, 255, 255, .055)));
  }
  nav.gd-tabbar .gd-tab, .gd-tabbar .gd-tab {
    appearance: none; background: none; border: 0; cursor: pointer;
    font-family: var(--game-sans);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; padding: 7px 2px 6px; min-height: 52px; border-radius: var(--g-r-ctl);
    color: var(--g-ink-7, #9d8fb8); font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase;
    transition: color var(--dur) var(--ease-out-expo), background var(--dur) var(--ease-out-expo), transform var(--dur) var(--ease-out-expo);
  }
  .gd-tabbar .gd-tab svg { width: 20px; height: 20px; stroke: currentColor; fill: none;
    stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
  .gd-tabbar .gd-tab:active { transform: scale(.94); }
  .gd-tabbar .gd-tab[aria-current="true"] { color: #fff; background: var(--g-lit-30, rgba(139, 92, 246, .30)); }
  .gd-tabbar .gd-tab .gd-badge { position: absolute; transform: translate(15px, -16px);
    min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--g-r-ctl);
    background: var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font-size: var(--t-label); line-height: 16px;
    font-variant-numeric: tabular-nums; }
  .gd-tabbar .gd-tab .gd-badge[hidden] { display: none; }
  /* nothing may hide behind the bar */
  body { padding-bottom: calc(78px + env(safe-area-inset-bottom, 0px)); }
  .gd-tab .gd-tab-avatar { width: 20px; height: 20px; border-radius: 50%; overflow: hidden; display: none; }
  .gd-tab .gd-tab-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .gd-tab.has-avatar svg { display: none; }
  .gd-tab.has-avatar .gd-tab-avatar { display: block; }
  #profileConsole .console-inner { padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px)) !important; }
}

/* ── profile console (the character sheet) ───────────────────────────────── */
/* The OAuth anchors carry display:inline-flex, which outranks the UA's [hidden]{display:none} —
   the buttons rendered while hidden (caught on the first screenshot, 2026-09-02). */
#profileConsole [hidden] { display: none !important; }
#profileConsole .pf-sheet { display: grid; gap: 14px; }
#profileConsole .pf-id { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
#profileConsole .pf-avatar {
  /* ONE circle, not two. This carried a solid 2px ring AND the XP progress ring is drawn as a
     second concentric circle at inset:-6px — on the dark ground they merged, on paper they read
     as two (operator 2026-09-03: "theres like two avatar circles in the profile sheet").
     The progress ring is the ring; the photo keeps a hairline so it still has an edge. */
  width: 72px; height: 72px; border-radius: 50%; background: var(--g-accent-25, rgba(102, 0, 204, .25)); border: 0;
  display: grid; place-items: center; overflow: hidden; font-size: var(--t-h2); color: #fff; flex: none; position: relative;
}
#profileConsole .pf-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
#profileConsole .pf-avatar input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
#profileConsole .pf-who h3 { font-size: var(--t-h3); margin: 0 0 2px; color: var(--g-ink, #e9e9f4); }
#profileConsole .pf-who .pf-handle { font-size: var(--t-data); letter-spacing: 1.4px; text-transform: uppercase; color: var(--g-ink-6, #6f6a8a); }
#profileConsole .pf-who .pf-bio { font-size: var(--t-data); color: var(--g-ink-2, #c9c4dc); margin-top: 6px; max-width: 560px; line-height: 1.55; }
#profileConsole .pf-level { display: grid; gap: 4px; min-width: 200px; flex: 1; }
#profileConsole .pf-level .pf-lv { display: flex; justify-content: space-between; font-size: var(--t-label); letter-spacing: 1.2px; text-transform: uppercase; color: var(--g-ink-6, #6f6a8a); }
#profileConsole .pf-level .pf-lv b { color: var(--g-hi, #ccb2ff); }
#profileConsole .pf-level .pf-xp { height: 6px; background: var(--g-accent-12, rgba(102, 0, 204, .12)); border: 1px solid var(--g-accent-3, rgba(102, 0, 204, .3)); border-radius: var(--g-r-ctl); overflow: hidden; }
#profileConsole .pf-level .pf-xp i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--g-accent, #6600cc), var(--g-hi-2, #b48cff)); transition: width .7s var(--ease-out-expo); }
#profileConsole .pf-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; }
#profileConsole .pf-stat { border: 1px solid var(--g-accent-3, rgba(102, 0, 204, .3)); background: var(--g-raise, rgba(255, 255, 255, .03)); padding: 9px 10px; }
#profileConsole .pf-stat b { display: block; font-size: var(--t-h3); color: var(--g-ink, #e9e9f4); font-variant-numeric: tabular-nums; }
#profileConsole .pf-stat span { font-size: var(--t-label); letter-spacing: 1.2px; text-transform: uppercase; color: var(--g-ink-6, #6f6a8a); }
#profileConsole .pf-tabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: 1px solid var(--g-accent-35, rgba(102, 0, 204, .35)); }
#profileConsole .pf-tab {
  background: none; border: 0; border-bottom: 2px solid transparent; color: var(--g-ink-6, #6f6a8a); font-family: inherit; font-size: var(--t-data);
  letter-spacing: 1.4px; text-transform: uppercase; padding: 8px 10px; cursor: pointer; margin-bottom: -1px; min-height: 40px;
}
#profileConsole .pf-tab[aria-selected="true"] { color: var(--g-hi, #ccb2ff); border-bottom-color: var(--gd-purple, var(--g-accent, #6600cc)); }
#profileConsole .pf-tab .pf-n { font-size: var(--t-label); color: var(--g-ink-7, #9d8fb8); margin-left: 4px; }
#profileConsole .pf-pane { max-height: 62vh; overflow-y: auto; padding-top: 6px; }
#profileConsole .pf-empty { font-size: var(--t-data); color: var(--g-ink-6, #6f6a8a); padding: 14px 0; line-height: 1.6; }
#profileConsole .pf-row { display: flex; gap: 10px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--g-accent-18, rgba(102, 0, 204, .18)); font-size: var(--t-data); }
#profileConsole .pf-row .pf-k { font-size: var(--t-label); letter-spacing: 1.2px; text-transform: uppercase; color: var(--g-ink-6, #6f6a8a); min-width: 62px; }
#profileConsole .pf-row .pf-t { flex: 1; min-width: 0; }
#profileConsole .pf-row .pf-t b { color: var(--g-ink, #e9e9f4); }
#profileConsole .pf-row .pf-t small { display: block; color: var(--g-ink-6, #6f6a8a); font-size: var(--t-label); margin-top: 2px; }
#profileConsole .pf-row .pf-q { font-variant-numeric: tabular-nums; color: var(--gd-purple, var(--g-accent, #6600cc)); white-space: nowrap; }
#profileConsole .pf-chip {
  display: inline-block; font-size: var(--t-label); letter-spacing: 1px; text-transform: uppercase; padding: 3px 7px; margin: 0 4px 4px 0;
  border: 1px solid var(--g-accent-4, rgba(102, 0, 204, .4)); color: var(--g-hi, #ccb2ff); background: var(--g-accent-06, rgba(102, 0, 204, .06));
}
#profileConsole .pf-chip.is-ok { border-color: rgba(127, 211, 155, .5); color: #7fd39b; background: rgba(127, 211, 155, .1); }
#profileConsole .pf-chip.is-warn { border-color: rgba(255, 143, 122, .6); color: #ff8f7a; background: rgba(255, 143, 122, .1); }
#profileConsole .pf-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
#profileConsole .pf-photos a { display: block; aspect-ratio: 1; overflow: hidden; border: 1px solid var(--g-accent-25, rgba(102, 0, 204, .25)); background: var(--g-raise, rgba(255, 255, 255, .03)); }
#profileConsole .pf-photos img { width: 100%; height: 100%; object-fit: cover; display: block; }
#profileConsole .pf-form { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); align-items: end; }
#profileConsole .pf-form label { display: grid; gap: 3px; font-size: var(--t-label); letter-spacing: 1.2px; text-transform: uppercase; color: var(--g-ink-6, #6f6a8a); }
#profileConsole .pf-form input, #profileConsole .pf-form select, #profileConsole .pf-form textarea {
  background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-5, rgba(102, 0, 204, .5)); color: var(--g-ink, #e9e9f4); padding: 8px 10px;
  font-family: inherit; font-size: 16px; min-height: 40px; width: 100%; box-sizing: border-box;
}
#profileConsole .pf-form textarea { min-height: 72px; resize: vertical; }
#profileConsole .pf-form .pf-wide { grid-column: 1 / -1; }
#profileConsole .pf-btn {
  background: var(--gd-purple, var(--g-accent, #6600cc)); border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font-family: inherit; font-size: var(--t-data);
  letter-spacing: 1.5px; text-transform: uppercase; padding: 9px 14px; cursor: pointer; min-height: 44px;
}
#profileConsole .pf-btn.is-ghost { background: none; color: var(--g-hi, #ccb2ff); }
#profileConsole .pf-btn:disabled { opacity: .5; cursor: default; }
#profileConsole .pf-links a { display: inline-block; margin: 0 8px 6px 0; font-size: var(--t-data); letter-spacing: 1px; text-transform: uppercase; color: var(--g-hi, #ccb2ff); }
#profileConsole .pf-note { font-size: var(--t-data); color: var(--g-hi, #ccb2ff); border-left: 2px solid var(--gd-purple, var(--g-accent, #6600cc)); background: var(--g-accent-08, rgba(102, 0, 204, .08)); padding: 8px 10px; }
#profileConsole .pf-note.is-bad { color: #ff8f7a; border-left-color: #ff8f7a; background: rgba(255, 143, 122, .1); }
#profileConsole .pf-auth { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; border-radius: var(--g-r-card); padding: 16px !important; border: 1px solid var(--g-accent-45, rgba(102, 0, 204, .45)); padding: 12px; font-size: var(--t-data); color: var(--g-ink-6, #6f6a8a); }
#profileConsole .pf-auth input { flex: 1 1 220px; min-width: 190px; max-width: 340px; border-radius: var(--g-r-ctl); background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-5, rgba(102, 0, 204, .5)); color: var(--g-ink, #e9e9f4); padding: 8px 10px; font-family: inherit; font-size: 16px; min-height: 40px; }
#profileConsole .pf-auth a.pf-oauth { background: none; border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: var(--g-hi, #ccb2ff); font-size: var(--t-data); letter-spacing: 1px; text-transform: uppercase; padding: 9px 12px; text-decoration: none; min-height: 40px; display: inline-flex; align-items: center; }
#profileConsole .pf-auth a.pf-oauth.is-discord { background: #5865F2; border-color: #5865F2; color: #fff; }
#profileConsole .pf-guest { display: grid; gap: 12px; }
#profileConsole .pf-guest .pf-guest-hero { font-size: var(--t-data); line-height: 1.7; color: var(--g-ink-2, #c9c4dc); }
#profileConsole .pf-guest .pf-guest-hero b, #profileConsole .pf-guest ul b { color: var(--g-hi, #ccb2ff); }
#profileConsole .pf-guest ul { margin: 0; padding-left: 18px; font-size: var(--t-data); line-height: 1.8; color: var(--g-ink-2, #c9c4dc); }
@media (prefers-reduced-motion: reduce) { #profileConsole .pf-level .pf-xp i { transition: none; } }

/* ── edit pane v2: avatar crop, link editor, even stat rows, scrollable tab strip (2026-09-02) ── */
#profileConsole .pf-id { position: relative; }
#profileConsole .pf-avatar-edit {
  position: absolute; left: 0; top: 54px; width: 72px; text-align: center; font-family: inherit; font-size: var(--t-label); letter-spacing: .14em; text-transform: uppercase;
  background: rgba(0, 0, 0, .55); color: #fff; border: 0; border-radius: 0 0 36px 36px; padding: 5px 0 6px; cursor: pointer; line-height: 1;
}
#profileConsole .pf-avatar-edit:hover, #profileConsole .pf-avatar-edit:focus-visible { background: var(--gd-purple, var(--g-accent, #6600cc)); }
#profileConsole .pf-links a { display: inline-flex; align-items: center; gap: 5px; margin: 0 10px 6px 0; font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase; text-decoration: none; }
#profileConsole .pf-links svg, #profileConsole .pf-linkicon svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
#profileConsole .pf-grid { grid-template-columns: repeat(6, 1fr); }
#profileConsole .pf-lbl { font-size: var(--t-label); letter-spacing: 1.2px; text-transform: uppercase; color: var(--g-ink-4, #8b86a8); margin-bottom: 6px; }
#profileConsole .pf-lbl small { text-transform: none; letter-spacing: 0; color: var(--g-ink-6, #6f6a8a); margin-left: 6px; }
#profileConsole .pf-linkrow { display: grid; grid-template-columns: 28px 130px 1fr 34px; gap: 6px; align-items: center; margin-bottom: 6px; }
#profileConsole .pf-linkicon { display: grid; place-items: center; width: 28px; height: 28px; color: var(--g-hi, #ccb2ff); }
#profileConsole .pf-linkrow input[aria-invalid="true"] { border-color: #ff8f7a; }
#profileConsole .pf-linkdel { appearance: none; background: none; border: 1px solid rgba(255, 143, 122, .5); color: #ff8f7a; width: 34px; height: 34px; border-radius: var(--g-r-ctl); cursor: pointer; font-size: var(--t-h3); line-height: 1; }
#profileConsole .pf-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
#profileConsole .pf-hint { font-size: var(--t-label); color: var(--g-ink-4, #8b86a8); line-height: 1.5; }
#profileConsole .pf-hint b { color: var(--g-hi, #ccb2ff); }
.pf-crop { position: fixed; inset: 0; z-index: 2000; background: rgba(5, 6, 15, .82); display: grid; place-items: center; padding: 16px; }
.pf-crop-card { background: var(--g-surface, #0b0c1a); border: 1px solid var(--g-line-3, rgba(194, 163, 255, .35)); padding: 18px; display: grid; gap: 12px; justify-items: center; color: var(--g-ink, #e9e9f4); font-family: inherit; max-width: 100%; }
.pf-crop-title { font-size: var(--t-label); letter-spacing: .18em; text-transform: uppercase; color: var(--g-hi, #ccb2ff); }
.pf-crop-stage { position: relative; overflow: hidden; touch-action: none; background: #000; border-radius: var(--g-r-ctl); }
.pf-crop-stage canvas { display: block; cursor: grab; }
.pf-crop-mask { position: absolute; inset: 0; pointer-events: none; box-shadow: 0 0 0 999px var(--g-scrim-2, rgba(5, 6, 15, .62)) inset; border-radius: 50%; }
.pf-crop-zoom { display: flex; align-items: center; gap: 10px; font-size: var(--t-label); letter-spacing: .14em; text-transform: uppercase; color: var(--g-ink-4, #8b86a8); width: 100%; }
.pf-crop-zoom input { flex: 1; accent-color: var(--gd-purple, var(--g-accent, #6600cc)); }
.pf-crop-hint { font-size: var(--t-label); color: var(--g-ink-6, #6f6a8a); letter-spacing: .06em; }
.pf-crop-actions { display: flex; gap: 8px; }
.pf-crop .pf-btn { background: var(--gd-purple, var(--g-accent, #6600cc)); border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font-family: inherit; font-size: var(--t-data); letter-spacing: 1.5px; text-transform: uppercase; padding: 9px 14px; cursor: pointer; min-height: 40px; }
.pf-crop .pf-btn.is-ghost { background: none; color: var(--g-hi, #ccb2ff); }
@media (max-width: 700px) {
  /* spatial pass for the phone: one column of identity, three-by-two stats, a tab strip that
     scrolls instead of wrapping, single-column forms. Six cells ÷ three columns = no hanging row. */
  #profileConsole .pf-id { flex-direction: column; align-items: center; text-align: center; gap: 10px; }
  #profileConsole .pf-avatar-edit { left: 50%; transform: translateX(-50%); }
  #profileConsole .pf-who { display: grid; justify-items: center; }
  #profileConsole .pf-level { width: 100%; min-width: 0; }
  #profileConsole .pf-grid { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  #profileConsole .pf-stat { padding: 8px 6px; text-align: center; }
  #profileConsole .pf-stat b { font-size: var(--t-h3); }
  #profileConsole .pf-stat span { font-size: var(--t-label); letter-spacing: .08em; }
  #profileConsole .pf-tabs { flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; scrollbar-width: none; margin: 0 -4px; padding: 0 4px; }
  #profileConsole .pf-tabs::-webkit-scrollbar { display: none; }
  #profileConsole .pf-tab { flex: 0 0 auto; scroll-snap-align: center; }
  #profileConsole .pf-form { grid-template-columns: 1fr; }
  #profileConsole .pf-linkrow { grid-template-columns: 28px 1fr 34px; grid-template-areas: "icon label del" "url url url"; }
  #profileConsole .pf-linkicon { grid-area: icon; } #profileConsole .pf-linklabel { grid-area: label; } #profileConsole .pf-linkurl { grid-area: url; } #profileConsole .pf-linkdel { grid-area: del; }
  #profileConsole .pf-row { flex-wrap: wrap; }
}

/* ── stash v2: a photo grid, public/private per item, the provenance seal (2026-09-02) ── */
#profileConsole .pf-stash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
#profileConsole .pf-card { border: 1px solid var(--g-accent-35, rgba(102, 0, 204, .35)); background: var(--g-raise, rgba(255, 255, 255, .03)); display: grid; grid-template-rows: auto 1fr auto; overflow: hidden; position: relative; }
#profileConsole .pf-card-img { aspect-ratio: 1; background: var(--g-accent-08, rgba(102, 0, 204, .08)); display: grid; place-items: center; color: var(--g-hi, #ccb2ff); cursor: pointer; overflow: hidden; }
#profileConsole .pf-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
#profileConsole .pf-card-img svg { width: 34px; height: 34px; stroke: currentColor; fill: none; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; opacity: .8; }
#profileConsole .pf-card-body { padding: 8px 9px 6px; display: grid; gap: 3px; min-width: 0; }
#profileConsole .pf-card-body b { font-size: var(--t-data); color: var(--g-ink, #e9e9f4); line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#profileConsole .pf-card-body small { font-size: var(--t-label); color: var(--g-ink-4, #8b86a8); letter-spacing: .04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#profileConsole .pf-card-body p { font-size: var(--t-label); color: var(--g-ink-2, #c9c4dc); line-height: 1.45; margin: 2px 0 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
#profileConsole .pf-card-foot { display: flex; gap: 4px; align-items: center; padding: 6px 7px 7px; border-top: 1px solid var(--g-accent-2, rgba(102, 0, 204, .2)); }
#profileConsole .pf-card-foot select { flex: 1; min-width: 0; font-size: 16px; padding: 5px 4px; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-4, rgba(102, 0, 204, .4)); color: var(--g-ink, #e9e9f4); font-family: inherit; min-height: 34px; }
#profileConsole .pf-ico { appearance: none; background: none; border: 1px solid var(--g-accent-4, rgba(102, 0, 204, .4)); color: var(--g-hi, #ccb2ff); width: 34px; height: 34px; border-radius: var(--g-r-ctl); cursor: pointer; display: grid; place-items: center; flex: none; }
#profileConsole .pf-ico svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
#profileConsole .pf-ico[aria-pressed="true"] { background: rgba(127, 211, 155, .15); border-color: rgba(127, 211, 155, .6); color: #7fd39b; }
#profileConsole .pf-ico.is-danger { color: #ff8f7a; border-color: rgba(255, 143, 122, .45); }
#profileConsole .pf-seal { position: absolute; top: 6px; left: 6px; display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; padding: 3px 6px; background: var(--g-scrim-3, rgba(5, 6, 15, .78)); color: #7fd39b; border: 1px solid rgba(127, 211, 155, .5); }
#profileConsole .pf-seal.is-unsigned { color: var(--g-hi, #ccb2ff); border-color: var(--g-line-5, rgba(194, 163, 255, .5)); }
#profileConsole .pf-seal svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 2; }
#profileConsole .pf-vis { position: absolute; top: 6px; right: 6px; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; padding: 3px 6px; background: var(--g-scrim-3, rgba(5, 6, 15, .78)); color: var(--g-ink-4, #8b86a8); border: 1px solid rgba(139, 134, 168, .4); }
#profileConsole .pf-vis.is-public { color: #7fd39b; border-color: rgba(127, 211, 155, .5); }
#profileConsole .pf-photo-pick { display: flex; gap: 8px; align-items: center; }
#profileConsole .pf-photo-pick .pf-thumb { width: 52px; height: 52px; border: 1px dashed var(--g-accent-5, rgba(102, 0, 204, .5)); display: grid; place-items: center; color: var(--g-hi, #ccb2ff); overflow: hidden; flex: none; cursor: pointer; }
#profileConsole .pf-photo-pick .pf-thumb img { width: 100%; height: 100%; object-fit: cover; }
#profileConsole .pf-photo-pick .pf-thumb svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.6; }
#profileConsole .pf-seg { display: inline-flex; border: 1px solid var(--g-accent-45, rgba(102, 0, 204, .45)); }
#profileConsole .pf-seg button { appearance: none; background: none; border: 0; color: var(--g-ink-4, #8b86a8); font-family: inherit; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; padding: 8px 12px; cursor: pointer; min-height: 40px; }
#profileConsole .pf-seg button[aria-pressed="true"] { background: var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; }
#profileConsole .pf-edit-inline { grid-column: 1 / -1; border: 1px solid var(--g-accent-45, rgba(102, 0, 204, .45)); padding: 10px; display: grid; gap: 8px; }
@media (max-width: 700px) {
  #profileConsole .pf-stash-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  #profileConsole .pf-card-foot { flex-wrap: wrap; }
  #profileConsole .pf-card-foot select { flex: 1 1 100%; }
}

/* ── the "+" composer ── */
.pf-crop-mask.is-square { border-radius: 0; box-shadow: none; outline: 2px solid rgba(255, 255, 255, .55); outline-offset: -2px; }
.pf-composer { width: min(520px, 100%); justify-items: stretch; }
.pf-composer textarea { width: 100%; box-sizing: border-box; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-5, rgba(102, 0, 204, .5)); color: var(--g-ink, #e9e9f4); padding: 8px 10px; font-family: inherit; font-size: 16px; resize: vertical; min-height: 64px; }
.pf-composer input, .pf-composer select { width: 100%; box-sizing: border-box; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-5, rgba(102, 0, 204, .5)); color: var(--g-ink, #e9e9f4); padding: 8px 10px; font-family: inherit; font-size: 16px; min-height: 40px; }
.pf-composer .pf-lbl { font-size: var(--t-label); letter-spacing: 1.2px; text-transform: uppercase; color: var(--g-ink-4, #8b86a8); }
.pf-composer .pf-seg { display: inline-flex; border: 1px solid var(--g-accent-45, rgba(102, 0, 204, .45)); }
.pf-composer .pf-seg button { appearance: none; background: none; border: 0; color: var(--g-ink-4, #8b86a8); font-family: inherit; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; padding: 8px 12px; cursor: pointer; min-height: 40px; }
.pf-composer .pf-seg button[aria-pressed="true"] { background: var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; }
.pf-composer .pf-seg button:disabled { opacity: .4; cursor: default; }
.pf-thumbs { display: flex; gap: 6px; flex-wrap: wrap; }
.pf-thumb-img { position: relative; width: 72px; height: 72px; overflow: hidden; border: 1px solid var(--g-accent-45, rgba(102, 0, 204, .45)); }
.pf-thumb-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pf-thumb-img button { position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; border-radius: 50%; border: 0; background: rgba(5, 6, 15, .8); color: #fff; font-size: var(--t-data); line-height: 20px; cursor: pointer; padding: 0; }
.pf-thumb-add {
  /* SIZE TO THE LABEL, not to a guess. It was a fixed 72px square holding "Camera or library"
     — seventeen characters at 8px with tracking — so the words sat outside the tile (operator
     2026-09-03: "post photos + CAMERA OR LIBRARY is like outside the bounds of the box").
     min-width keeps the tile square when the label is short, padding lets it grow when it is
     not, and the label is centred either way. */
  min-width: 72px; width: auto; height: 72px; padding: 0 8px; box-sizing: border-box;
  text-align: center; line-height: 1.25; border: 1px dashed var(--g-accent-6, rgba(102, 0, 204, .6)); background: none; color: var(--g-hi, #ccb2ff); display: grid; place-items: center; gap: 2px; font-family: inherit; font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase; cursor: pointer; padding: 4px; }
.pf-thumb-add svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 2; }

/* ── FX: toasts, unlock reveal, burst (2026-09-02, "game feel") ── */
.fx-toasts { position: fixed; left: 50%; bottom: calc(92px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); z-index: 2500; display: grid; gap: 6px; pointer-events: none; width: min(420px, calc(100vw - 32px)); }
@media (min-width: 701px) { .fx-toasts { left: auto; right: 16px; bottom: 76px; transform: none; } }
.fx-toast { display: flex; align-items: center; gap: 10px; background: var(--g-surface-4, rgba(8, 9, 18, .94)); color: var(--g-ink, #e9e9f4); border: 1px solid var(--g-line-3, rgba(194, 163, 255, .35)); padding: 10px 14px; font-family: var(--game-mono); font-size: var(--t-label); letter-spacing: .06em; opacity: 0; transform: translateY(8px) scale(.98); transition: opacity var(--dur) var(--ease-out-expo), transform var(--dur) var(--ease-out-expo); box-shadow: 0 10px 30px rgba(0, 0, 0, .35); }
.fx-toast.is-in { opacity: 1; transform: none; }
.fx-toast.is-out { opacity: 0; transform: translateY(-6px); }
.fx-toast.is-bad { border-color: rgba(255, 143, 122, .6); color: #ffb4a6; }
.fx-toast.is-ok { border-color: rgba(127, 211, 155, .5); }
.fx-toast-ico { font-size: var(--t-body); line-height: 1; }
.fx-toast-txt { flex: 1; min-width: 0; }
.fx-toast-pts { color: #7fd39b; font-variant-numeric: tabular-nums; }
.fx-burst { position: fixed; inset: 0; z-index: 2600; pointer-events: none; }
.fx-unlock { position: fixed; inset: 0; z-index: 2400; background: rgba(5, 6, 15, .72); display: grid; place-items: center; padding: 16px; opacity: 0; transition: opacity var(--dur) var(--ease-out-expo); }
.fx-unlock.is-in { opacity: 1; }
.fx-unlock-card { width: min(360px, 100%); text-align: center; background: var(--g-surface, #0b0c1a); border: 1px solid var(--g-line-4, rgba(194, 163, 255, .4)); padding: 26px 22px 20px; color: var(--g-ink, #e9e9f4); font-family: var(--game-mono); transform: scale(.92) translateY(8px); transition: transform var(--dur) var(--ease-out-expo); }
.fx-unlock.is-in .fx-unlock-card { transform: none; }
.fx-unlock-card.is-silver { border-color: rgba(220, 220, 235, .55); } .fx-unlock-card.is-gold { border-color: rgba(255, 210, 110, .7); box-shadow: 0 0 40px rgba(255, 210, 110, .18); }
.fx-unlock-kicker { font-size: var(--t-label); letter-spacing: .3em; text-transform: uppercase; color: var(--g-hi, #ccb2ff); }
.fx-unlock-ico { font-size: var(--t-d2); line-height: 1.2; margin: 10px 0 6px; filter: drop-shadow(0 0 18px rgba(194, 163, 255, .6)); }
.fx-unlock-name { font-size: var(--t-h3); letter-spacing: .06em; text-transform: uppercase; color: #fff; }
.fx-unlock-desc { font-size: var(--t-label); color: var(--g-ink-4, #8b86a8); margin-top: 6px; line-height: 1.5; }
.fx-unlock-meta { display: flex; justify-content: center; gap: 12px; margin-top: 10px; font-size: var(--t-label); letter-spacing: .14em; text-transform: uppercase; color: var(--g-ink-4, #8b86a8); }
.fx-unlock-meta b { color: #7fd39b; }
.fx-unlock-ok { margin-top: 16px; background: var(--gd-purple, var(--g-accent, #6600cc)); border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font-family: inherit; font-size: var(--t-data); letter-spacing: 1.5px; text-transform: uppercase; padding: 9px 22px; cursor: pointer; min-height: 40px; }

/* ── continuity: consoles slide in, panes cross-fade, images fade in, skeletons instead of "Loading…" ── */
@keyframes gd-console-in { from { opacity: 0; transform: translate(-50%, 14px); } to { opacity: 1; transform: translate(-50%, 0); } }
.console.active { animation: gd-console-in .26s cubic-bezier(.2, .8, .2, 1) both; }
@media (max-width: 768px) { @keyframes gd-console-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } } }
@keyframes gd-pane-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
#profileConsole .pf-pane > * { animation: gd-pane-in .22s ease both; }
#profileConsole img[data-fade] { opacity: 0; transition: opacity var(--dur) var(--ease-out-expo); } #profileConsole img[data-fade].is-loaded { opacity: 1; }
.pf-skel { display: grid; gap: 12px; }
.pf-skel i { display: block; background: linear-gradient(90deg, var(--g-raise-3, rgba(255, 255, 255, .05)), var(--g-lip-3, rgba(255, 255, 255, .12)), var(--g-raise-3, rgba(255, 255, 255, .05))); background-size: 200% 100%; animation: pf-shimmer 1.2s linear infinite; border-radius: var(--g-r-ctl); }
@keyframes pf-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .console.active, #profileConsole .pf-pane > *, .fx-toast, .fx-unlock-card { animation: none; transition: none; } }

/* ── progression: the XP ring, the catalogue, the quest log ── */
#profileConsole .pf-ring { position: absolute; inset: -6px; width: calc(100% + 12px); height: calc(100% + 12px); transform: rotate(-90deg); pointer-events: none; }
#profileConsole .pf-ring circle { fill: none; stroke-width: 3; }
#profileConsole .pf-ring .bg { stroke: var(--g-accent-25, rgba(102, 0, 204, .25)); } #profileConsole .pf-ring .fg { stroke: var(--g-hi-2, #b48cff); stroke-linecap: round; transition: stroke-dashoffset .9s var(--ease-out-expo); }
#profileConsole .pf-avatar { overflow: visible; }
#profileConsole .pf-avatar > img, #profileConsole .pf-avatar-inner { border-radius: 50%; overflow: hidden; width: 100%; height: 100%; display: grid; place-items: center; box-shadow: inset 0 0 0 1px var(--g-line-3, rgba(194, 163, 255, .35)); }
#profileConsole .pf-next { font-size: var(--t-label); color: var(--g-ink-4, #8b86a8); letter-spacing: .06em; margin-top: 2px; }
#profileConsole .pf-next b { color: var(--g-hi, #ccb2ff); }
#profileConsole .pf-cat { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
#profileConsole .pf-ach { border: 1px solid var(--g-accent-35, rgba(102, 0, 204, .35)); background: var(--g-raise, rgba(255, 255, 255, .03)); padding: 10px; display: grid; gap: 4px; position: relative; }
#profileConsole .pf-ach.is-locked { opacity: .55; filter: grayscale(1); }
#profileConsole .pf-ach.is-locked:hover { opacity: .85; }
#profileConsole .pf-ach .ico { font-size: var(--t-h2); line-height: 1.1; }
#profileConsole .pf-ach b { font-size: var(--t-data); color: var(--g-ink, #e9e9f4); letter-spacing: .04em; }
#profileConsole .pf-ach small { font-size: var(--t-label); color: var(--g-ink-4, #8b86a8); line-height: 1.4; }
#profileConsole .pf-ach .tier { position: absolute; top: 8px; right: 8px; font-size: var(--t-label); letter-spacing: .14em; text-transform: uppercase; padding: 2px 6px; border: 1px solid var(--g-line-3, rgba(194, 163, 255, .35)); color: var(--g-hi, #ccb2ff); }
#profileConsole .pf-ach.t-silver .tier { border-color: rgba(220, 220, 235, .5); color: #dcdceb; } #profileConsole .pf-ach.t-gold .tier { border-color: rgba(255, 210, 110, .6); color: #ffd26e; }
#profileConsole .pf-ach .bar { height: 4px; background: var(--g-accent-15, rgba(102, 0, 204, .15)); border-radius: var(--g-r-ctl); overflow: hidden; margin-top: 4px; }
#profileConsole .pf-ach .bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--g-accent, #6600cc), var(--g-hi-2, #b48cff)); }
#profileConsole .pf-ach .pts { font-size: var(--t-label); color: #7fd39b; letter-spacing: .1em; }
#profileConsole .pf-quest { border: 1px solid rgba(127, 211, 155, .35); background: rgba(127, 211, 155, .06); padding: 10px 12px; display: grid; gap: 6px; }
#profileConsole .pf-quest .q-title { font-size: var(--t-label); letter-spacing: .18em; text-transform: uppercase; color: #7fd39b; display: flex; justify-content: space-between; }
#profileConsole .pf-quest .q-title button { background: none; border: 0; color: var(--g-ink-4, #8b86a8); font-family: inherit; font-size: var(--t-label); cursor: pointer; }
#profileConsole .pf-quest ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
#profileConsole .pf-quest li { display: flex; align-items: center; gap: 8px; font-size: var(--t-data); color: var(--g-ink-2, #c9c4dc); cursor: pointer; }
#profileConsole .pf-quest li.is-done { color: var(--g-ink-6, #6f6a8a); text-decoration: line-through; }
#profileConsole .pf-quest li .q-box { width: 16px; height: 16px; border: 1px solid rgba(127, 211, 155, .6); display: grid; place-items: center; font-size: var(--t-label); color: #7fd39b; flex: none; }
#profileConsole .pf-feed { display: grid; gap: 4px; margin-top: 12px; }
#profileConsole .pf-feed div { display: flex; justify-content: space-between; font-size: var(--t-label); color: var(--g-ink-4, #8b86a8); border-bottom: 1px solid var(--g-accent-15, rgba(102, 0, 204, .15)); padding: 4px 0; }
#profileConsole .pf-feed b { color: #7fd39b; }

/* ── the bell: a notifications panel above the HUD ── */
.gd-notes { position: fixed; right: 16px; bottom: 76px; z-index: 1450; width: min(360px, calc(100vw - 32px)); background: var(--g-surface-2, rgba(8, 9, 18, .96)); border: 1px solid var(--g-line-3, rgba(194, 163, 255, .35)); box-shadow: 0 12px 40px rgba(0, 0, 0, .4); color: var(--g-ink, #e9e9f4); font-family: var(--game-mono); font-size: var(--t-label); display: grid; }
.gd-notes-head { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; border-bottom: 1px solid rgba(194, 163, 255, .2); letter-spacing: .14em; text-transform: uppercase; font-size: var(--t-label); color: var(--g-hi, #ccb2ff); }
.gd-notes-head button { background: none; border: 0; color: var(--g-ink-4, #8b86a8); font-family: inherit; font-size: var(--t-label); letter-spacing: .1em; text-transform: uppercase; cursor: pointer; }
.gd-notes-list { max-height: 50vh; overflow-y: auto; }
.gd-note { padding: 9px 12px; border-bottom: 1px solid rgba(194, 163, 255, .12); display: grid; gap: 2px; cursor: pointer; }
.gd-note.is-unread { background: var(--g-accent-12, rgba(102, 0, 204, .12)); }
.gd-note b { color: #fff; font-weight: normal; letter-spacing: .04em; } .gd-note span { color: var(--g-ink-4, #8b86a8); } .gd-note small { color: #5c5878; font-size: var(--t-label); }
.gd-notes-empty { padding: 16px 12px; color: var(--g-ink-4, #8b86a8); }

/* ── the "+" create menu, and the game layer's own type (never the document's serif) ── */
#profileConsole, #gdHud, .gd-tabbar, .gd-notes, .fx-toast, .fx-unlock-card, .pf-crop-card, .pf-create-card { font-family: var(--game-sans); }
#profileConsole .console-header, #gdHud, .gd-notes, .fx-toast, .fx-unlock-kicker, .fx-unlock-meta, .pf-crop-title, .pf-crop-zoom, .pf-crop-hint, .pf-create-card small { font-family: var(--game-mono); }
#profileConsole .pf-plus { width: 40px; height: 40px; border-radius: 50%; background: var(--gd-purple, var(--g-accent, #6600cc)); border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font: 700 var(--t-h2)/1 Inter, system-ui, sans-serif; cursor: pointer; margin-right: 8px; display: grid; place-items: center; box-shadow: 0 0 0 0 var(--g-lit-5, rgba(139, 92, 246, .5)); transition: transform var(--dur) var(--ease-out-expo), box-shadow var(--dur) var(--ease-out-expo); }
#profileConsole .pf-plus:hover { transform: scale(1.06); box-shadow: 0 0 0 6px var(--g-lit-18, rgba(139, 92, 246, .18)); }
#profileConsole .pf-plus[hidden] { display: none; }
.pf-create { position: fixed; inset: 0; z-index: 2300; background: var(--g-scrim, rgba(5, 6, 15, .55)); display: grid; place-items: end center; opacity: 0; transition: opacity var(--dur) var(--ease-out-expo); }
.pf-create.is-in { opacity: 1; }
.pf-create-card { width: min(520px, 100%); background: var(--g-surface, #0b0c1a); border: 1px solid var(--g-line-4, rgba(194, 163, 255, .4)); border-bottom: 0; border-radius: var(--g-r-panel) var(--g-r-panel) 0 0; padding: 12px 12px calc(14px + env(safe-area-inset-bottom, 0px)); display: grid; gap: 6px; position: relative; transform: translateY(24px); transition: transform var(--dur) var(--ease-out-expo); }
.pf-create.is-in .pf-create-card { transform: none; }
@media (min-width: 701px) { .pf-create { place-items: center; } .pf-create-card { border-radius: var(--g-r-panel); border-bottom: 1px solid var(--g-line-4, rgba(194, 163, 255, .4)); padding-bottom: 12px; } }
.pf-create-card [data-make] { display: flex; align-items: center; gap: 14px; text-align: left; background: var(--g-raise, rgba(255, 255, 255, .03)); border: 1px solid var(--g-line-2, rgba(194, 163, 255, .18)); color: var(--g-ink, #e9e9f4); padding: 12px 14px; cursor: pointer; font-family: inherit; border-radius: var(--g-r-card); min-height: 64px; transition: background var(--dur) var(--ease-out-expo), border-color var(--dur) var(--ease-out-expo); }
.pf-create-card [data-make]:hover, .pf-create-card [data-make]:focus-visible { background: var(--g-accent-18, rgba(102, 0, 204, .18)); border-color: var(--g-line-5, rgba(194, 163, 255, .5)); }
.pf-create-card .ico { width: 40px; height: 40px; border-radius: var(--g-r-card); background: var(--g-accent-25, rgba(102, 0, 204, .25)); display: grid; place-items: center; color: var(--g-hi, #ccb2ff); flex: none; }
.pf-create-card .ico svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.pf-create-card b { display: block; font-size: var(--t-body); letter-spacing: .02em; }
.pf-create-card small { display: block; font-size: var(--t-label); color: var(--g-ink-4, #8b86a8); margin-top: 2px; line-height: 1.4; }
.pf-create-x { position: absolute; top: -44px; right: 0; width: 36px; height: 36px; border-radius: 50%; background: rgba(8, 9, 18, .9); border: 1px solid var(--g-line-4, rgba(194, 163, 255, .4)); color: #fff; font-size: var(--t-h3); cursor: pointer; }
@media (min-width: 701px) { .pf-create-x { top: -14px; right: -14px; } }
/* the profile console slides in as one piece; animate the INNER so a site's own .console transform is untouched */
.console.active { animation: none; }
@keyframes gd-inner-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
#profileConsole.active .console-inner { animation: gd-inner-in .26s cubic-bezier(.2, .8, .2, 1) both; }

/* ── panel pass (2026-09-02): the HUD as a right-edge rail, a scrim, masks, custom controls, two columns ── */
@media (min-width: 701px) {
  /* CENTRED BY LAYOUT, NOT BY TRANSFORM. `top:50%; translateY(-50%)` on an element whose height
     is fractional lands the whole rail on a half pixel — measured live 2026-09-04:
     translateY(-183.32px) on a 366.64px-tall rail, on EVERY page of both sites. A composited
     layer at a fractional offset smears its text at 1x and looks perfect at 2x, which is exactly
     what the operator reported: "blurry on one of my screens but not on the sharper mac screen".
     inset + margin auto is the same centring the consoles already use, and layout positions get
     pixel-snapped for text rasterisation where transforms do not. */
  #gdHud { right: 12px; top: 0; bottom: 0; margin-block: auto; height: fit-content; transform: none; flex-direction: column; padding: 6px; gap: 2px; border-radius: var(--g-r-panel); }
  #gdHud .gd-hud-btn { flex-direction: column; gap: 4px; padding: 9px 8px; min-width: 64px; font-size: var(--t-label); letter-spacing: .1em; text-align: center; }
  #gdHud .gd-hud-btn svg { width: 19px; height: 19px; }
  #gdHud .gd-hud-sep { width: auto; height: 1px; margin: 4px 8px; }
  #gdHud .gd-hud-name { align-items: center; }
  #gdHud .gd-hud-n { position: absolute; top: 4px; right: 6px; }
  #gdHud .gd-hud-btn { position: relative; }
  .gd-notes { right: 88px; bottom: auto; top: 50%; transform: translateY(-50%); }
  .fx-toasts { right: 88px; bottom: 24px; }
}
.pf-scrim { position: fixed; inset: 0; z-index: 999; background: var(--g-scrim-2, rgba(5, 6, 15, .62)); -webkit-backdrop-filter: blur(10px) saturate(90%); backdrop-filter: blur(10px) saturate(90%); animation: gd-scrim-in .25s ease both; }
.pf-scrim[hidden] { display: none; }
@keyframes gd-scrim-in { from { opacity: 0; } to { opacity: 1; } }
#profileConsole .pf-close { width: 44px; height: 44px; border-radius: 50%; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-line-3, rgba(194, 163, 255, .35)); color: var(--g-hi, #ccb2ff); cursor: pointer; display: grid; place-items: center; padding: 0; }
#profileConsole .pf-close svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
#profileConsole .pf-close:hover { background: var(--g-accent-25, rgba(102, 0, 204, .25)); color: #fff; }
#profileConsole .pf-plus { width: auto; min-width: 44px; height: 44px; border-radius: var(--g-r-panel); padding: 0 14px 0 10px; gap: 8px; display: inline-flex; align-items: center; font: 700 var(--t-data)/1 Inter, system-ui, sans-serif; letter-spacing: .12em; text-transform: uppercase; }
#profileConsole .pf-plus-glyph { font-size: var(--t-h3); line-height: 1; }
@media (max-width: 700px) { #profileConsole .pf-plus { padding: 0; width: 44px; } #profileConsole .pf-plus-word { display: none; } }
#profileConsole .pf-tabs { -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent); }
@media (min-width: 701px) { #profileConsole .pf-tabs { -webkit-mask-image: none; mask-image: none; } }
.gd-tickwrap, .gh-tickwrap { -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.kingdom-bar .kingdom-btn { background: rgba(8, 9, 18, .72) !important; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
@media (max-width: 1100px) { .kingdom-bar { flex-wrap: nowrap !important; overflow-x: auto; justify-content: flex-start !important; scrollbar-width: none; -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 28px), transparent); } .kingdom-bar::-webkit-scrollbar { display: none; } .kingdom-bar .kingdom-btn { flex: 0 0 auto; } }
#profileConsole .pf-max { display: inline-block; font-size: var(--t-label); letter-spacing: .2em; padding: 2px 6px; border: 1px solid rgba(255, 210, 110, .6); color: #ffd26e; margin-right: 6px; vertical-align: middle; }
#profileConsole .pf-sheet.is-max .pf-xp i { background: linear-gradient(90deg, #ffd26e, #fff2c2); }
#profileConsole .pf-status { display: inline-flex; align-items: center; gap: 6px; flex: 1; min-width: 0; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-4, rgba(102, 0, 204, .4)); color: var(--g-ink, #e9e9f4); font-family: inherit; font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase; padding: 0 10px; min-height: 34px; cursor: pointer; border-radius: var(--g-r-ctl); }
#profileConsole .pf-status i, .pf-menu i { width: 7px; height: 7px; border-radius: 50%; background: #7fd39b; flex: none; }
.pf-menu { position: fixed; z-index: 2350; min-width: 170px; background: var(--g-surface, #0b0c1a); border: 1px solid var(--g-line-4, rgba(194, 163, 255, .4)); box-shadow: 0 12px 40px rgba(0, 0, 0, .5); display: grid; padding: 4px; font-family: Inter, system-ui, sans-serif; }
.pf-menu [role="option"] { display: flex; align-items: center; gap: 8px; background: none; border: 0; color: var(--g-ink, #e9e9f4); font: var(--t-label)/1 Inter, system-ui, sans-serif; letter-spacing: .08em; text-transform: uppercase; padding: 9px 10px; cursor: pointer; text-align: left; border-radius: var(--g-r-ctl); min-height: 36px; }
.pf-menu [role="option"]:hover, .pf-menu [role="option"][aria-selected="true"] { background: var(--g-accent-25, rgba(102, 0, 204, .25)); }
#profileConsole .pf-vis { cursor: pointer; display: inline-flex; align-items: center; gap: 4px; font-family: inherit; }
#profileConsole .pf-vis svg { width: 11px; height: 11px; stroke: currentColor; fill: none; stroke-width: 2; }
#profileConsole .pf-card-img.is-empty { flex-direction: column; gap: 4px; color: var(--g-ink-4, #8b86a8); font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; }
#profileConsole .pf-card-img.is-empty svg { width: 26px; height: 26px; }
#profileConsole .pf-card-img.is-empty:hover { color: var(--g-hi, #ccb2ff); background: var(--g-accent-16, rgba(102, 0, 204, .16)); }
#profileConsole .pf-foot { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; padding-bottom: 4px;
  border-top: 1px solid var(--g-line, rgba(194,163,255,.16)); padding-top: 12px; }
#profileConsole .pf-foot .pf-btn { font-size: var(--t-label); letter-spacing: .1em; padding: 7px 12px; min-height: 34px; opacity: .85; }
#profileConsole .pf-foot .pf-btn:hover, #profileConsole .pf-foot .pf-btn:focus-visible { opacity: 1; }
@media (min-width: 1000px) {
  #profileConsole .pf-sheet { grid-template-columns: 340px 1fr; gap: 20px; align-items: start; }
  #profileConsole .pf-side { display: grid; gap: 14px; position: sticky; top: 0; }
  #profileConsole .pf-main { min-width: 0; }
  #profileConsole .pf-id { flex-direction: column; align-items: center; text-align: center; }
  #profileConsole .pf-who { display: grid; justify-items: center; }
  #profileConsole .pf-level { width: 100%; }
  #profileConsole .pf-grid { grid-template-columns: repeat(3, 1fr); }
  #profileConsole .pf-pane { max-height: 70vh; }
  #profileConsole .pf-avatar-edit { left: 50%; transform: translateX(-50%); }
}
/* the rail owns the right 112px of the viewport: page containers may not extend under it. A wide
   screen is unaffected (its containers never reach that far); a tablet or a 1280px desktop with a
   1200px frame is pulled in so no control at the right edge is ever covered (panel finding #1). */
/* SYMMETRY, not just clearance. The rule below reserved the rail on the RIGHT only and set an
   8px left margin, so a page clear of the rail was also visibly lopsided: measured 2026-09-10
   at 1440px (a stock MacBook width) the catalogue filter sat 116px from the left and 224px
   from the right. Worse, the lopsidedness only appeared BELOW ~1500px — above it the page
   centred normally, so the layout changed character mid-resize. Operator: "the filters are
   left aligned on a page that should be symmetrical."
   Reserving the rail on BOTH sides costs one rail of width and buys a page that is centred at
   every width. The clearance guarantee is unchanged — the right gutter is still rail + 24. */
body.has-rail main, body.has-rail .frame, body.has-rail .footer, body.has-rail > footer { max-width: calc(100vw - 2 * (var(--rail-w, 90px) + 24px)) !important; margin-left: calc(var(--rail-w, 90px) + 24px) !important; margin-right: calc(var(--rail-w, 90px) + 24px) !important; }
/* ...but ONLY ONCE. On SBI, .frame is a DESCENDANT of main, so both selectors above match and
   the rail reservation is applied TWICE, nested. The inner frame then exceeds the space its own
   margins leave it and main's align-items:center centres the overflow, pushing its left edge
   NEGATIVE — content is clipped off the left of the screen.
   Measured live 2026-09-04, .frame left edge: home -34px at 768, 1024 AND 1280 (a stock MacBook
   width); registry -34 at 768, -44 at 1024. At 1024 the registry lost the first character of
   every heading — "36,041 TOTAL ACCESSIONS" read as "041 TOTAL ACCESSIONS", a different and
   smaller number — while a wide dead gutter sat on the right.
   An inner .frame must not reserve rail space again; main already did. Inert on GD, which has
   no .frame element at any width (measured, not assumed). Found by the parallel SBI session. */
body.has-rail main .frame { max-width: 100% !important; margin-left: 0 !important; margin-right: 0 !important; }
@media (min-width: 701px) {
  /* the rail is compact and fixed-width: a long name never widens it into the page */
  #gdHud { width: 92px; box-sizing: border-box; }
  #gdHud .gd-hud-btn { width: 100%; min-width: 0; padding-left: 4px; padding-right: 4px; }
  #gdHud .gd-hud-name { max-width: 100%; align-items: center; }
  #gdHud .gd-hud-name > span, #gdHud .gd-hud-name small { display: block; max-width: 76px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; }
  #gdHud .gd-hud-bar { width: 56px; }
}
@media (min-width: 701px) and (max-width: 1100px) { #gdHud .gd-hud-btn { min-width: 56px; padding: 8px 6px; } }

/* ── accessibility seat (2026-09-02): contrast, target sizes, label size, card row wrap ── */
#profileConsole .pf-stat span, #profileConsole .pf-lv, #profileConsole .pf-next, #profileConsole .pf-lbl, #profileConsole .pf-row .pf-k, #profileConsole .pf-row .pf-t small, #profileConsole .pf-card-body small, #profileConsole .pf-hint, #profileConsole .pf-empty, #profileConsole .pf-who .pf-handle, #profileConsole .pf-ach small, #profileConsole .pf-feed div, #profileConsole .pf-quest li.is-done, #profileConsole .cm-meta, .fx-unlock-desc, .fx-unlock-meta, .pf-crop-hint, .pf-crop-zoom, .pf-create-card small, .gd-note span { color: var(--g-ink-3, #a8a3c6); }
#profileConsole .pf-quest li .q-box { width: 24px; height: 24px; }
#profileConsole .pf-quest li { min-height: 32px; }
#profileConsole .pf-avatar-edit { font-size: var(--t-label); letter-spacing: .1em; padding: 6px 0 7px; top: 50px; }
#profileConsole .pf-vis { min-height: 26px; padding: 4px 8px; font-size: var(--t-label); }
#profileConsole .pf-card-foot { flex-wrap: wrap; }
#profileConsole .pf-card-foot .pf-status { flex: 1 1 100%; }
#profileConsole .pf-ico { width: 40px; height: 40px; }

/* the splash text is centred whatever the host page's body does (SBI's flex body left-aligned it on the phone) */
#gdBoot .gd-boot-word, #gdBoot .gd-boot-sub, #gdBoot .gd-boot-hint { width: 100%; text-align: center; box-sizing: border-box; padding: 0 16px; }
#gdBoot .gd-boot-hint { left: 0; right: 0; }
/* the page is hidden from the FIRST paint when a splash is about to run (html.gd-booting is set by an inline snippet) */
html.gd-booting body > *:not(#gdBoot) { visibility: hidden; }

/* ── the feed (2026-09-02): the community as a feed on the game shell — cards, threads, nested comments, the inbox ── */
#feedConsole, .fd-write, .fd-why { font-family: var(--game-sans); }
#feedConsole .console-header, .pf-crop-title { font-family: var(--game-mono); }
/* THE SHELL — for both consoles. Measured 2026-09-02: every generated sub-page (GD strain pages,
   community/grow/disclosure, SBI registry pages) carries ZERO .console rules, so the profile console
   had no geometry there at all; and each home page's own .console (GD: a bottom sheet with !important
   geometry; SBI: a centred card faded in by opacity) won on some property and broke the panel. So the
   game layer carries the complete geometry itself, at higher priority: one dark bottom sheet, the same
   on every page of both sites. */
#profileConsole.console, #feedConsole.console { display: none !important; position: fixed !important; inset: 0 !important;  transform: none !important; width: min(980px, 94vw) !important; max-width: min(980px, 94vw) !important; height: fit-content !important; max-height: min(88vh, 940px) !important; margin: auto !important; box-sizing: border-box !important; overflow-y: auto !important; -webkit-overflow-scrolling: touch; z-index: 1000 !important; opacity: 1 !important; pointer-events: auto !important; transition: none !important var(--dur) var(--ease-out-expo); background: var(--g-surface-3, rgba(8, 9, 18, .97)) !important; color: var(--g-ink, #e9e9f4) !important; border: 1px solid rgba(194, 163, 255, .3) !important; border-bottom: 0 !important; border-radius: var(--g-r-panel) var(--g-r-panel) 0 0 !important; box-shadow: 0 -20px 80px rgba(0, 0, 0, .6) !important; padding: 14px 16px calc(76px + env(safe-area-inset-bottom, 0px)) !important; font-size: var(--t-data); line-height: 1.5; }
#profileConsole.console.active, #feedConsole.console.active { display: block !important; }
@media (max-width: 700px) { #profileConsole.console, #feedConsole.console { inset: 0 !important; margin: 0 !important; transform: none !important; width: 100vw !important; max-width: 100vw !important; height: 100dvh !important; max-height: 100dvh !important; border: 0 !important; border-radius: 0 !important; padding: 10px 12px calc(76px + env(safe-area-inset-bottom, 0px)) !important; } }
#feedConsole [hidden] { display: none !important; }
#feedConsole .console-inner { display: grid; gap: 10px; max-width: 720px; margin: 0 auto; }
#feedConsole.active .console-inner { animation: gd-inner-in .26s cubic-bezier(.2, .8, .2, 1) both; }
#feedConsole .console-header { display: flex; align-items: center; gap: 6px; color: var(--g-hi, #ccb2ff); border-bottom: 1px solid var(--g-accent-35, rgba(102, 0, 204, .35)); padding-bottom: 8px; letter-spacing: .08em; text-transform: uppercase; font-size: var(--t-data); }
#feedConsole .fd-hbtn, #feedConsole .pf-close { width: 44px; height: 44px; border-radius: 50%; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-line-3, rgba(194, 163, 255, .35)); color: var(--g-hi, #ccb2ff); cursor: pointer; display: grid; place-items: center; padding: 0; position: relative; flex: none; }
#feedConsole .fd-hbtn svg, #feedConsole .pf-close svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
#feedConsole .fd-hbtn:hover, #feedConsole .pf-close:hover { background: var(--g-accent-25, rgba(102, 0, 204, .25)); color: #fff; }
#feedConsole .fd-hbtn.is-warn { color: #ff8f7a; border-color: rgba(255, 143, 122, .5); }
#feedConsole .fd-hbtn i { position: absolute; top: -2px; right: -2px; min-width: 18px; height: 18px; border-radius: var(--g-r-ctl); background: #7fd39b; color: #05060f; font: 700 var(--t-label)/18px Inter, system-ui, sans-serif; text-align: center; font-style: normal; padding: 0 4px; }
#feedConsole .fd-new { height: 44px; border-radius: var(--g-r-panel); padding: 0 14px 0 10px; display: inline-flex; align-items: center; gap: 6px; background: var(--gd-purple, var(--g-accent, #6600cc)); border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font: 700 var(--t-label)/1 Inter, system-ui, sans-serif; letter-spacing: .12em; text-transform: uppercase; cursor: pointer; flex: none; }
#feedConsole .fd-new svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2.2; stroke-linecap: round; }
@media (max-width: 700px) { #feedConsole .fd-new { width: 44px; padding: 0; justify-content: center; } #feedConsole .fd-new span { display: none; } }
#feedConsole .fd-body { display: grid; gap: 10px; }
#feedConsole .fd-signin { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; border: 1px solid var(--g-accent-45, rgba(102, 0, 204, .45)); padding: 12px 14px; font-size: var(--t-data); color: var(--g-ink-2, #c9c4dc); line-height: 1.5; }
#feedConsole .fd-signin span { flex: 1; min-width: 200px; }
#feedConsole .fd-compose { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: var(--g-raise, rgba(255, 255, 255, .03)); border: 1px solid rgba(194, 163, 255, .22); color: var(--g-ink-4, #8b86a8); padding: 10px 12px; border-radius: var(--g-r-panel); cursor: text; font: var(--t-lead)/1.3 Inter, system-ui, sans-serif; min-height: 56px; }
#feedConsole .fd-compose:hover, #feedConsole .fd-compose:focus-visible { border-color: var(--g-line-5, rgba(194, 163, 255, .5)); color: var(--g-ink-2, #c9c4dc); }
#feedConsole .fd-compose-hint { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#feedConsole .fd-compose svg { width: 22px; height: 22px; stroke: var(--g-hi, #ccb2ff); fill: none; stroke-width: 2.2; stroke-linecap: round; flex: none; }
#feedConsole .fd-tabs { display: flex; align-items: center; gap: 2px; border-bottom: 1px solid var(--g-accent-35, rgba(102, 0, 204, .35)); overflow-x: auto; scrollbar-width: none; }
#feedConsole .fd-tabs::-webkit-scrollbar { display: none; }
/* The row scrolls, and with the scrollbar hidden a clipped last label reads as broken rather
   than as "there is more". A mask on the trailing edge says scrollable without adding chrome:
   it fades only when the row actually overflows, because mask-image on a row that fits would
   dim a perfectly visible tab for no reason. */
#feedConsole .fd-tabs { scroll-snap-type: x proximity; scroll-padding-left: 2px; }
#feedConsole .fd-tabs > * { scroll-snap-align: start; }
@supports (mask-image: linear-gradient(#000, #000)) {
  #feedConsole .fd-tabs.is-scrollable {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent 100%);
    mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent 100%);
  }
}
#feedConsole .fd-tab { background: none; border: 0; border-bottom: 2px solid transparent; color: var(--g-ink-5, #8a85a6); font: 600 var(--t-data)/1 Inter, system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; padding: 12px 12px; cursor: pointer; margin-bottom: -1px; min-height: 44px; white-space: nowrap; flex: none; }
#feedConsole .fd-tab[aria-selected="true"] { color: var(--g-ink, #e9e9f4); border-bottom-color: var(--gd-purple, var(--g-accent, #6600cc)); }
#feedConsole .pf-seg { display: inline-flex; border: 1px solid var(--g-accent-4, rgba(102, 0, 204, .4)); border-radius: var(--g-r-ctl); overflow: hidden; flex: none; margin-left: 8px; }
#feedConsole .pf-seg button { background: none; border: 0; color: var(--g-ink-5, #8a85a6); font: 600 var(--t-label)/1 Inter, system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; padding: 0 10px; min-height: 32px; cursor: pointer; }
#feedConsole .pf-seg button[aria-pressed="true"] { background: var(--g-accent-35, rgba(102, 0, 204, .35)); color: #fff; }
#feedConsole .fd-count { font-size: var(--t-label); letter-spacing: .14em; text-transform: uppercase; color: var(--g-ink-3, #a8a3c6); }
#feedConsole .fd-list { display: grid; gap: 10px; }
#feedConsole .fd-card { display: grid; gap: 10px; background: rgba(255, 255, 255, .025); border: 1px solid var(--g-line, rgba(194, 163, 255, .16)); border-radius: var(--g-r-panel); padding: 12px 14px; transition: border-color var(--dur) var(--ease-out-expo), opacity var(--dur) var(--ease-out-expo); }
#feedConsole .fd-card:hover { border-color: rgba(194, 163, 255, .34); }
#feedConsole .fd-card.is-hiding, #feedConsole .fd-comment.is-hiding { opacity: .35; }
#feedConsole .fd-head { display: flex; align-items: center; gap: 10px; }
#feedConsole .fd-avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--g-accent-3, rgba(102, 0, 204, .3)); border: 1px solid var(--g-line-4, rgba(194, 163, 255, .4)); color: #fff; display: grid; place-items: center; font: 700 var(--t-lead)/1 Inter, system-ui, sans-serif; flex: none; }
#feedConsole .fd-avatar.sm { width: 28px; height: 28px; font-size: var(--t-label); }
#feedConsole .fd-avatar.is-else { background: rgba(255, 255, 255, .06); color: var(--g-ink-2, #c9c4dc); }
#feedConsole .fd-who { flex: 1; min-width: 0; display: grid; gap: 2px; }
#feedConsole .fd-who b { font-size: var(--t-body); color: var(--g-ink, #e9e9f4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#feedConsole .fd-who small { font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
#feedConsole .fd-tag { display: inline-flex; align-items: center; gap: 3px; color: #a0e6b9; }
#feedConsole .fd-tag svg, #feedConsole .fd-cults svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; }
#feedConsole .fd-seal { font-size: var(--t-label); letter-spacing: .1em; text-transform: uppercase; color: #7fd39b; border: 1px solid rgba(127, 211, 155, .5); padding: 1px 6px; border-radius: var(--g-r-ctl); }
#feedConsole .fd-seal.is-gold { color: #ffd26e; border-color: rgba(255, 210, 110, .6); }
#feedConsole .fd-score { font: 700 var(--t-label)/1 var(--game-mono); color: var(--g-hi, #ccb2ff); border: 1px solid var(--g-line-4, rgba(194, 163, 255, .4)); padding: 5px 7px; border-radius: var(--g-r-ctl); flex: none; }
#feedConsole .fd-title { margin: 0; font-size: var(--t-body); line-height: 1.3; color: var(--g-ink, #e9e9f4); cursor: pointer; }
#feedConsole [data-open]:focus-visible, #feedConsole .fd-tab:focus-visible, #feedConsole .fd-act:focus-visible { outline: 2px solid var(--g-hi, #ccb2ff); outline-offset: 2px; border-radius: var(--g-r-ctl); }
#feedConsole .fd-photos { display: grid; gap: 4px; border-radius: var(--g-r-card); overflow: hidden; }
#feedConsole .fd-photos.n1 { grid-template-columns: 1fr; }
#feedConsole .fd-photos.n2, #feedConsole .fd-photos.n4 { grid-template-columns: 1fr 1fr; }
#feedConsole .fd-photos.n3 { grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; }
#feedConsole .fd-photos.n3 > :first-child { grid-row: 1 / 3; }
#feedConsole .fd-photos > * { display: block; position: relative; aspect-ratio: 1; background: var(--g-raise-2, rgba(255, 255, 255, .04)); cursor: pointer; }
#feedConsole .fd-photos.n1 > * { aspect-ratio: 4 / 3; }
#feedConsole .is-full .fd-photos { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
#feedConsole .is-full .fd-photos > * { aspect-ratio: 1; }
#feedConsole .is-full .fd-photos > :first-child { grid-column: 1 / -1; aspect-ratio: 4 / 3; }
#feedConsole .fd-photos img { width: 100%; height: 100%; object-fit: cover; display: block; }
#feedConsole .fd-photos b { position: absolute; inset: 0; display: grid; place-items: center; background: var(--g-scrim, rgba(5, 6, 15, .55)); color: #fff; font-size: var(--t-h3); }
#feedConsole .fd-text { font-size: var(--t-body); line-height: 1.55; color: #d9d5ea; overflow-wrap: anywhere; }
#feedConsole .fd-text p { margin: 0 0 8px; }
#feedConsole .fd-text p:last-child { margin-bottom: 0; }
#feedConsole .fd-text.is-clamp { display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; cursor: pointer; }
#feedConsole .fd-text a, #feedConsole .cm-link { color: #a0e6b9; text-decoration: underline; text-decoration-color: rgba(160, 230, 185, .4); text-underline-offset: 2px; }
#feedConsole .fd-log { display: flex; flex-wrap: wrap; gap: 8px 16px; font-size: var(--t-data); color: var(--g-ink-5, #8a85a6); border-top: 1px solid var(--g-accent-2, rgba(102, 0, 204, .2)); padding-top: 8px; }
#feedConsole .fd-log b { color: var(--g-ink, #e9e9f4); font-variant-numeric: tabular-nums; }
#feedConsole .fd-smoke { flex-basis: 100%; color: var(--g-ink-2, #c9c4dc); line-height: 1.5; }
#feedConsole .fd-foot, #feedConsole .fd-cact { display: flex; align-items: center; gap: 4px; }
/* 44px, not 36. .fd-act IS the vote button — the control the operator could not hit on the
   first community post. That turned out to be pool exhaustion, but the target was undersized
   too, and a 36px vote button on a phone is its own reason to miss. .fd-reply .pf-btn below
   already used 44, so the standard was known here and applied unevenly. */
#feedConsole .fd-act { display: inline-flex; align-items: center; gap: 6px; background: none; border: 1px solid transparent; color: var(--g-ink-5, #8a85a6); font: 600 var(--t-data)/1 Inter, system-ui, sans-serif; padding: 0 10px; min-height: 44px; border-radius: var(--g-r-panel); cursor: pointer; }
#feedConsole .fd-act svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
#feedConsole .fd-act:hover { background: var(--g-raise-3, rgba(255, 255, 255, .05)); color: var(--g-ink, #e9e9f4); }
#feedConsole .fd-act[aria-pressed="true"] { color: var(--g-hi, #ccb2ff); }
#feedConsole .fd-act[aria-pressed="true"] svg { fill: currentColor; }
#feedConsole .fd-act.is-danger { color: #ff8f7a; margin-left: auto; }
#feedConsole .fd-act.is-danger:hover { background: rgba(255, 143, 122, .12); }
#feedConsole .fd-act[data-report] { margin-left: auto; }
#feedConsole .fd-else { text-decoration: none; color: inherit; }
#feedConsole .fd-else > .fd-head > svg { width: 18px; height: 18px; stroke: var(--g-ink-5, #8a85a6); fill: none; stroke-width: 1.8; flex: none; }
#feedConsole .fd-cults { display: flex; align-items: center; gap: 6px; font-size: var(--t-data); color: #a0e6b9; }
#feedConsole .fd-comments { display: grid; gap: 6px; }
#feedConsole .fd-reply { display: flex; align-items: center; gap: 8px; }
#feedConsole .fd-reply input { flex: 1; min-width: 0; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-5, rgba(102, 0, 204, .5)); color: var(--g-ink, #e9e9f4); padding: 0 14px; font: var(--t-lead)/1 Inter, system-ui, sans-serif; min-height: 44px; border-radius: var(--g-r-panel); }
#feedConsole .fd-reply .pf-btn { background: var(--gd-purple, var(--g-accent, #6600cc)); border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font: 700 var(--t-label)/1 Inter, system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; padding: 0 14px; min-height: 44px; border-radius: var(--g-r-panel); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
#feedConsole .fd-reply .pf-btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; }
#feedConsole .fd-reply .pf-btn:disabled { opacity: .5; }
#feedConsole .fd-reply.is-inline { margin-top: 6px; }
#feedConsole .fd-comment { display: flex; gap: 10px; padding: 10px 0 0; }
#feedConsole .fd-cbody { flex: 1; min-width: 0; display: grid; gap: 4px; border-left: 2px solid var(--g-accent-22, rgba(102, 0, 204, .22)); padding-left: 10px; }
#feedConsole .fd-cwho b { font-size: var(--t-data); color: var(--g-ink, #e9e9f4); }
#feedConsole .fd-cwho small { font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); margin-left: 6px; }
#feedConsole .fd-comment .fd-text { font-size: var(--t-data); }
#feedConsole .fd-kids { display: grid; }
#feedConsole .fd-kids .fd-comment { margin-left: 0; }
#feedConsole .fd-kids .fd-kids .fd-kids .fd-cbody { border-left-color: var(--g-accent-1, rgba(102, 0, 204, .1)); }
#feedConsole .fd-answers { color: #a0e6b9; margin-left: 6px; }
#feedConsole .fd-reply-to { font-size: var(--t-label); color: #a0e6b9; white-space: nowrap; flex: none; }
#feedConsole .fd-blurb { margin: 0; font-size: var(--t-data); color: var(--g-ink-3, #a8a3c6); line-height: 1.5; }
#feedConsole .fd-out { display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase; color: var(--g-ink-3, #a8a3c6); white-space: nowrap; }
#feedConsole .fd-out svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.fd-write-hint { margin: 0; font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); line-height: 1.5; }
.fx-toast.fd-undo .fd-undo-btn { margin-left: 10px; background: none; border: 1px solid var(--g-line-5, rgba(194, 163, 255, .5)); color: var(--g-hi, #ccb2ff); font: 700 var(--t-label)/1 Inter, system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; padding: 6px 10px; border-radius: var(--g-r-ctl); cursor: pointer; min-height: 28px; }
#feedConsole .fd-convo { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: rgba(255, 255, 255, .025); border: 1px solid var(--g-line, rgba(194, 163, 255, .16)); color: inherit; padding: 10px 12px; border-radius: var(--g-r-card); cursor: pointer; font-family: inherit; }
#feedConsole .fd-convo .fd-cbody { border: 0; padding: 0; }
#feedConsole .fd-convo b { font-size: var(--t-body); color: var(--g-ink, #e9e9f4); display: flex; align-items: center; gap: 6px; }
#feedConsole .fd-convo small { font-size: var(--t-data); color: var(--g-ink-5, #8a85a6); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
#feedConsole .fd-when { color: var(--g-ink-3, #a8a3c6); font-size: var(--t-label); flex: none; }
#feedConsole .fd-dot { width: 8px; height: 8px; border-radius: 50%; background: #7fd39b; display: inline-block; }
#feedConsole .fd-dm { display: grid; gap: 6px; max-height: 55vh; overflow-y: auto; padding: 4px 0; }
#feedConsole .fd-msg { max-width: 78%; justify-self: start; background: var(--g-raise-3, rgba(255, 255, 255, .05)); border-radius: var(--g-r-panel) 14px 14px 4px; padding: 8px 12px; font-size: var(--t-body); line-height: 1.45; display: grid; gap: 2px; }
#feedConsole .fd-msg.is-mine { justify-self: end; background: var(--g-accent-35, rgba(102, 0, 204, .35)); border-radius: var(--g-r-panel) 14px 4px 14px; }
#feedConsole .fd-msg small { font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); }
#feedConsole .pf-empty { font-size: var(--t-data); color: var(--g-ink-5, #8a85a6); padding: 18px 0; line-height: 1.6; text-align: center; }
/* #fdSignin is this button: the single conversion action for a signed-out visitor, 4px short. */
#feedConsole .pf-btn { background: var(--gd-purple, var(--g-accent, #6600cc)); border: 1px solid var(--gd-purple, var(--g-accent, #6600cc)); color: #fff; font: 700 var(--t-label)/1 Inter, system-ui, sans-serif; letter-spacing: .1em; text-transform: uppercase; padding: 0 14px; min-height: 44px; cursor: pointer; border-radius: var(--g-r-ctl); }
.fd-write { display: grid; gap: 10px; }
.fd-write textarea, .fd-write input { background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-5, rgba(102, 0, 204, .5)); color: var(--g-ink, #e9e9f4); padding: 10px 12px; font: var(--t-lead)/1.5 Inter, system-ui, sans-serif; width: 100%; box-sizing: border-box; border-radius: var(--g-r-ctl); resize: vertical; }
.fd-write-note { margin: 0; font-size: var(--t-data); color: var(--g-hi, #ccb2ff); border-left: 2px solid var(--gd-purple, var(--g-accent, #6600cc)); background: var(--g-accent-08, rgba(102, 0, 204, .08)); padding: 8px 10px; }
.fd-write-note.is-bad { color: #ff8f7a; border-left-color: #ff8f7a; background: rgba(255, 143, 122, .1); }
.pf-menu.fd-why { z-index: 2400; }
@media (min-width: 701px) {
    /* EVERY OTHER CONSOLE clears the rail too. The rule below names #profileConsole and
     #feedConsole by id, so the rest ran underneath: measured 2026-09-04 with checkout OPEN,
     12 of 25 fields under the rail on GD at 768/1024/1280 and 11 of 23 on SBI at 768/1024 —
     the shipping selector "DOMESTIC SEEDS ($15.00)" among them. That is the buy path.
     WIDTH ONLY, deliberately. The two sites anchor their consoles differently — GD is
     left:0/right:0 full-bleed at 768 and left:50% + translateX(-50%) at 1280; SBI is
     transform-centred throughout — so touching left/right/transform fixes one and throws the
     other off screen (I did exactly that first: GD's consoles landed at [326,954] in a 768
     viewport). Capping the width to the centred-safe figure clears the rail under BOTH
     anchorings without knowing which is in use. */
  /* NOT GATED ON body.has-rail, and that gating was the bug. railGuard() adds has-rail only when
     MAIN reaches the rail — but a console is a FIXED overlay whose width comes from the viewport,
     not from main, so it crosses the rail whether or not the page container does. Narrowing main
     to the canon's 1152 proved it: has-rail went false, these rules went inert, and genomeConsole
     and checkoutConsole ran to 1411 against a rail starting at 1336 — 3 of 7 and 13 of 26 fields
     under it, the checkout among them. The page being clear of the rail says nothing about an
     overlay drawn over both. The condition that matters is simply: IS THE RAIL VISIBLE, which
     hud.js measures into body.rail-on — a real width and not display:none. Not :has(#gdHud):
     that matches the element EXISTING, and hud.js hides the same element at phone widths. */
  body.rail-on .console { max-width: calc(100vw - 2 * (var(--rail-w, 90px) + 24px)) !important; }
  body.rail-on #profileConsole.console, body.rail-on #feedConsole.console { max-width: min(1100px, calc(100vw - var(--rail-w, 90px) - 72px)) !important; right: calc(var(--rail-w, 90px) + 24px) !important; transform: none !important; }

  /* EVERY console, not two of them by id. This named #profileConsole and #feedConsole only,
     so the other six ran under the rail: measured 2026-09-04 with SBI's checkout OPEN, 11 of
     23 fields sat under the rail at 768 and 1024 — including the shipping selector reading
     "DOMESTIC SEEDS ($15.00)". That is the buy path, on a tablet. The sites carry
     checkout/compare/fieldNotes/genealogy/growShop/terminal (SBI) and checkout/genome (GD)
     besides the two the rule knew about; a class selector covers whatever is added next. */
  /* A READING MEASURE. The feed had one; the profile did not, so its prose ran the full
     width of the panel — an 1,100px line is about twice what anyone reads comfortably. */
  #feedConsole .console-inner, #profileConsole .console-inner { max-width: 760px; margin-inline: auto; width: 100%; }
  #feedConsole .fd-card { padding: 14px 16px; }
}
@media (prefers-reduced-motion: reduce) { #feedConsole.active .console-inner { animation: none; } }

/* UI seat (2026-09-02): one control language in the tab row, a labelled score, a neutral queue icon, a lighter reply box, a distinct Close on the phone */
#feedConsole .fd-hbtn.is-warn { color: var(--g-hi, #ccb2ff); border-color: var(--g-line-3, rgba(194, 163, 255, .35)); }
#feedConsole .fd-score::after { content: "LOG"; font-size: var(--t-label); letter-spacing: .1em; margin-left: 4px; opacity: .7; }
#feedConsole .fd-tabs .pf-seg { border: 0; border-radius: 0; margin-left: 8px; align-self: stretch; }
#feedConsole .fd-tabs .pf-seg button { border-bottom: 2px solid transparent; margin-bottom: -1px; padding: 0 10px; min-height: 44px; }
#feedConsole .fd-tabs .pf-seg button[aria-pressed="true"] { background: none; color: var(--g-ink, #e9e9f4); border-bottom-color: var(--gd-purple, var(--g-accent, #6600cc)); }
#feedConsole .fd-reply.is-inline input { border-color: var(--g-accent-35, rgba(102, 0, 204, .35)); }
#feedConsole .pf-close { background: var(--g-lip-2, rgba(255, 255, 255, .08)); }
@media (max-width: 700px) { #feedConsole .console-header { gap: 12px; } }
#feedConsole .fd-answers.is-gone { color: var(--g-ink-3, #a8a3c6); font-style: italic; }
/* the in-place sign-in code (2026-09-02) */
#profileConsole #pfCode { flex: 1; min-width: 160px; background: var(--g-raise-2, rgba(255, 255, 255, .04)); border: 1px solid var(--g-accent-5, rgba(102, 0, 204, .5)); color: var(--g-ink, #e9e9f4); padding: 8px 12px; font: 700 var(--t-h2)/1 var(--game-mono); /* was a bare ui-monospace stack — the canon is two families and a mono FALLBACK rendering means the webfont did not arrive */ letter-spacing: .22em; min-height: 44px; text-align: center; }
#profileConsole .pf-auth-alt { flex-basis: 100%; font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); }
#profileConsole .pf-linkbtn { background: none; border: 0; padding: 0; color: var(--g-hi, #ccb2ff); font: inherit; text-decoration: underline; cursor: pointer; min-height: 0; }

/* claims + the moderation queue, moved into the feed console (2026-09-02) */
#feedConsole .fd-claim { display: grid; gap: 10px; border: 1px solid rgba(194, 163, 255, .25); border-radius: var(--g-r-card); padding: 14px; }
#feedConsole .fd-claim-h { margin: 0; font-size: var(--t-body); color: var(--g-ink, #e9e9f4); }
#feedConsole .fd-code { margin: 0; font: 700 var(--t-h2)/1 var(--game-mono); letter-spacing: .18em; color: #a0e6b9; text-align: center; padding: 12px; border: 1px dashed rgba(160, 230, 185, .5); border-radius: var(--g-r-ctl); }
#feedConsole .fd-note { margin: 0; font-size: var(--t-data); color: var(--g-hi, #ccb2ff); border-left: 2px solid var(--gd-purple, var(--g-accent, #6600cc)); background: var(--g-accent-08, rgba(102, 0, 204, .08)); padding: 8px 10px; }
#feedConsole .fd-note.is-ok { color: #7fd39b; border-left-color: #7fd39b; background: rgba(127, 211, 155, .1); }
#feedConsole .fd-note.is-bad { color: #ff8f7a; border-left-color: #ff8f7a; background: rgba(255, 143, 122, .1); }

/* The "post a grow" invitation on a cultivar's own page. It reuses the feed's compose strip so
   it is the same control the community console shows, not a second thing that looks like it. */
.gd-addgrow { margin-top: 14px; }
.gd-addgrow .fd-compose { width: 100%; }
/* A <button> DOES NOT INHERIT font-family — the same lesson this file already learned for
   .gd-tabbar, one component along. `.gd-addgrow .fd-compose` set only a width, so outside
   #feedConsole the compose button fell to the UA default and rendered ARIAL: measured
   2026-09-23 as the single stray family on a GD strain page (Inter, JetBrains Mono, Arial).
   Both storefronts carry this file and both carried the defect. */
.fd-compose, .fd-compose-hint { font-family: var(--game-sans); }


/* ── PROFILE SHEET: GRID CHILDREN MUST BE ABLE TO SHRINK ────────────────────────────────────
   Operator 2026-09-04: "the profile section on the left is still lobsided boxes and still
   overlapping the column on the right." A grid or flex item defaults to min-width:auto, which
   means it REFUSES to shrink below its content's minimum — a long word, an email address, a URL
   — and then overflows its track into the neighbouring column. It is the same fault that pushed
   the NOTIFY ME button 8px out of its row, and it is the standard cause of exactly this symptom.
   Every child of the sheet's grids can shrink now, and long unbroken strings wrap instead of
   forcing a track wider than its share. */
#profileConsole .pf-grid > *, #profileConsole .pf-form > *, #profileConsole .pf-linkrow > *,
#profileConsole .pf-photos > *, #profileConsole .pf-pane > *, #profileConsole .pf-id > * {
  min-width: 0; }
#profileConsole .pf-pane, #profileConsole .pf-grid, #profileConsole .pf-form { max-width: 100%; }
#profileConsole .pf-who, #profileConsole .pf-who h3, #profileConsole .pf-links a,
#profileConsole .pf-hint, #profileConsole .pf-note { overflow-wrap: anywhere; }

/* The XP ring is the ONLY circle around the avatar and it is concentric BY CONSTRUCTION:
   centred on the avatar's own box rather than offset by a negative inset that any padding,
   border or box-sizing change could throw off (reported off-centre twice). */
#profileConsole .pf-avatar { position: relative; box-sizing: border-box; }
#profileConsole .pf-ring {
  position: absolute; left: 50%; top: 50%; inset: auto;
  width: calc(100% + 12px); height: calc(100% + 12px);
  margin-left: calc((100% + 12px) / -2); margin-top: calc((100% + 12px) / -2);
  transform: rotate(-90deg); pointer-events: none; }

/* ── A grower, opened from their name on a post ──────────────────────────────
   The endpoint (api/profile.js) always existed; nothing ever linked to it, so
   the inbox could say "open a grower's profile to write to them" while no such
   door was on the page. Operator 2026-09-04: "also why cant i click into the
   profiles? like on a post". The author is now the door, on cards and comments. */
#feedConsole .fd-avatar.is-who,
#feedConsole .fd-wholink { appearance: none; -webkit-appearance: none; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; text-align: left; }
#feedConsole .fd-wholink { background: none; border: 0; display: flex; flex-direction: column; justify-content: center; min-height: 44px; max-width: 100%; }
#feedConsole .fd-wholink > b { transition: color var(--dur) var(--ease-out-expo); }
#feedConsole .fd-wholink:hover > b, #feedConsole .fd-wholink:focus-visible > b { color: var(--g-accent-ink, #c2a3ff); text-decoration: underline; text-underline-offset: 2px; }
/* .is-who is the avatar that OPENS the grower — a real button at 38px. Only the interactive
   one grows; the decorative .fd-avatar and the 28px .sm in comments are unchanged. The name
   beside it fills the same 44px row, so the header gains nothing in height from either. */
/* SELLING FROM THE STASH. The price field is revealed by the For-sale toggle rather than
   sitting there greyed out — an input you cannot use is a question the reader has to answer
   before they can ignore it. The chip on the card is how a grower sees, at a glance, which of
   their things are actually listed. */
.pf-sale, .pf-price { display: flex; flex-direction: column; gap: 4px; }
.pf-salehint { margin: 2px 0 0; }
.pf-chip.is-sale { display: inline-block; margin-top: 4px; font: 700 var(--t-label)/1.6 Inter, system-ui, sans-serif;
  letter-spacing: .08em; padding: 0 8px; border-radius: var(--g-r-panel);
  background: var(--g-accent-3, rgba(102, 0, 204, .3)); color: var(--g-hi, #ccb2ff); }
#feedConsole .fd-avatar.is-who { width: 44px; height: 44px; transition: border-color var(--dur) var(--ease-out-expo), transform var(--dur) var(--ease-out-expo); }
#feedConsole .fd-avatar.is-who:hover { border-color: var(--g-accent-ink, #c2a3ff); transform: translateY(-1px); }
#feedConsole .fd-cwho .fd-wholink { display: inline-block; }

#feedConsole .fd-invite { margin: 18px 2px 4px; padding: 14px 16px; text-align: center;
  border: 1px dashed var(--g-line-3, rgba(194, 163, 255, .35)); border-radius: var(--g-r-card, 7px);
  color: var(--g-ink-2, #c9c5e0); font-size: var(--t-data); line-height: 1.5; background: var(--g-fill, rgba(194, 163, 255, .05)); }
#feedConsole .gw { display: grid; gap: 14px; }
#feedConsole .gw-head { display: flex; align-items: center; gap: 12px; }
#feedConsole .gw-face { width: 56px; height: 56px; border-radius: 50%; flex: none; display: grid; place-items: center;
  background: var(--g-accent-3, rgba(102, 0, 204, .3)); border: 1px solid var(--g-line-4, rgba(194, 163, 255, .4));
  color: #fff; font: 700 var(--t-h2)/1 Inter, system-ui, sans-serif; }
#feedConsole .gw-id { flex: 1; min-width: 0; display: grid; gap: 3px; }
#feedConsole .gw-id h3 { margin: 0; font: 700 var(--t-h3)/1.2 Inter, system-ui, sans-serif; color: var(--g-ink, #e9e9f4); overflow: hidden; text-overflow: ellipsis; }
#feedConsole .gw-id small { font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#feedConsole .gw-tick { font-style: normal; color: var(--g-accent-ink, #c2a3ff); font-size: var(--t-body); }
#feedConsole .gw-bio { margin: 0; font-size: var(--t-data); line-height: 1.55; color: var(--g-ink-2, #c9c5e0); }
#feedConsole .gw-stats { display: flex; flex-wrap: wrap; gap: 16px; padding: 10px 0; border-block: 1px solid var(--g-line, rgba(194, 163, 255, .16)); }
#feedConsole .gw-stat { font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); }
#feedConsole .gw-stat b { font: 700 var(--t-lead)/1 var(--game-mono, ui-monospace, monospace); color: var(--g-ink, #e9e9f4); margin-right: 5px; }
#feedConsole .gw-badges { display: flex; flex-wrap: wrap; gap: 7px; }
#feedConsole .gw-badge { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border-radius: var(--g-r-ctl, 5px);
  border: 1px solid var(--g-line, rgba(194, 163, 255, .16)); background: var(--g-fill, rgba(194, 163, 255, .05));
  font-size: var(--t-label); color: var(--g-ink-2, #c9c5e0); }
#feedConsole .gw-badge i { font-style: normal; color: var(--g-accent-ink, #c2a3ff); }
#feedConsole .gw-h { margin: 4px 0 0; font: 600 var(--t-label)/1 var(--game-mono, ui-monospace, monospace); letter-spacing: .12em; text-transform: uppercase; color: var(--g-ink-3, #a8a3c6); }
#feedConsole .gw-threads { display: grid; gap: 7px; }
#feedConsole .gw-thread { display: grid; gap: 3px; width: 100%; text-align: left; padding: 11px 13px; cursor: pointer;
  border: 1px solid var(--g-line, rgba(194, 163, 255, .16)); border-radius: var(--g-r-card, 7px);
  background: var(--g-fill, rgba(194, 163, 255, .05)); transition: border-color var(--dur) var(--ease-out-expo), background var(--dur) var(--ease-out-expo); }
#feedConsole .gw-thread:hover { border-color: var(--g-line-4, rgba(194, 163, 255, .4)); background: var(--g-fill-2, rgba(194, 163, 255, .09)); }
#feedConsole .gw-thread b { font-size: var(--t-body); color: var(--g-ink, #e9e9f4); }
#feedConsole .gw-thread small { font-size: var(--t-label); color: var(--g-ink-3, #a8a3c6); }
#feedConsole .gw-stash { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 9px; }
#feedConsole .gw-item { margin: 0; display: grid; gap: 5px; min-width: 0; }
#feedConsole .gw-item img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--g-r-card, 7px); border: 1px solid var(--g-line, rgba(194, 163, 255, .16)); display: block; }
#feedConsole .gw-item figcaption { font-size: var(--t-label); line-height: 1.35; color: var(--g-ink-3, #a8a3c6); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
@media (max-width: 560px) {
  #feedConsole .gw-face { width: 46px; height: 46px; font-size: var(--t-h3); }
  #feedConsole .gw-id h3 { font-size: var(--t-body); }
  #feedConsole .gw-stash { grid-template-columns: repeat(auto-fill, minmax(94px, 1fr)); }
}

/* EVERY CONTROL A FINGER CAN REACH IS 44PX ON A TOUCH SCREEN (2026-09-13). Seed Bank International's
   tests/touch-target-size.test.mjs read its port of this layer and found nine shared controls under 44px
   with no touch raise; the same nine are here. Each grows only on a coarse pointer, so the desktop layout
   is unchanged, and each sits in a container that grows with it (the dock is a column flex, the profile
   tabs wrap, the segment controls are inline-flex, the toast sizes to its content), so a taller control
   moves its neighbours instead of overlapping them. The thumbnail's remove button keeps its 20px circle
   exactly where it sat, 2px in from the corner, painted as a gradient on a 44px button whose remaining
   area is hit area inside the tile (the tile clips overflow, so the area cannot extend outside it).
   SBI carries the same block in its own game.css (8c011a7b4). Its file cannot simply be re-ported from
   this one: on 2026-09-13 the two differed by 135 lines in both directions. */
@media (pointer: coarse) {
  #gdHud .gd-hud-btn { min-height: 44px; }
  #profileConsole .pf-tab { min-height: 44px; }
  .pf-crop .pf-btn { min-height: 44px; }
  #profileConsole .pf-seg button { min-height: 44px; }
  .pf-composer .pf-seg button { min-height: 44px; }
  .pf-thumb-img button { top: 0; right: 0; width: 44px; height: 44px; box-sizing: border-box; padding: 2px 2px 22px 22px; border-radius: 0; background: radial-gradient(circle at calc(100% - 12px) 12px, rgba(5, 6, 15, .8) 10px, transparent 10.5px); line-height: 20px; }
  #profileConsole .pf-foot .pf-btn { min-height: 44px; }
  #feedConsole .pf-seg button { min-height: 44px; }
  .fx-toast.fd-undo .fd-undo-btn { min-height: 44px; }
}
