/* @foundation/ui design tokens — CSS custom-property mirror of tokens.js.
   COMBINATION B "Ivory Study" — The Study's ceremonial structure in the
   Broadsheet's warm cream + gold palette; Playfair Display type. */

:root {
  /* --- Viewport insets ----------------------------------------------------
     ONE owner for the iPhone home-indicator allowance. It used to be applied
     in two places at once (the chat wrapper AND the composer), so the phone
     double-counted it and left ~86px of dead cream under the message box.
     Anything that needs the allowance reads this, and nothing adds env() itself.

     --bbl-kb is how much of the layout viewport an on-screen keyboard is
     covering, published by useKeyboardInset(). Zero on desktop and whenever the
     keyboard is down. */
  --bbl-kb: 0px;
  --bbl-safe-bottom: env(safe-area-inset-bottom, 0px);

  --bbl-bg:         #f4f1e9;
  --bbl-bg-soft:    #ece7d9;
  --bbl-bg-deep:    #e3dcc9;
  --bbl-bg-handoff: #f1ead7;
  --bbl-card:       #fbfaf4;

  --bbl-navy:        #171410;
  --bbl-navy-soft:   #272219;
  --bbl-navy-medium: #332c20;
  --bbl-navy-deep:   #0d0b07;

  /* A real navy blue for the "you" chat bubble — the --bbl-navy role is a dark
     neutral in this palette (near-black), so the sender bubble needs its own
     genuinely-blue fill that carries white text on both grounds. */
  --bbl-chat-mine:   #33466b;

  /* Meeting scratchpad "pens" — the two partners write in one shared pad, so
     authorship has to read at a glance without a label: Maxim in a dark
     neutral grey, Jackson in a dark navy. Both must clear text contrast on
     the cream card, and lighten (never invert) on the dark ground. */
  --bbl-pen-maxim:      #4a4a4a;
  --bbl-pen-jackson:    #1e3a5f;
  --bbl-pen-maxim-bg:   rgba(74, 74, 74, 0.05);
  --bbl-pen-jackson-bg: rgba(30, 58, 95, 0.05);

  --bbl-gold:       #b07a24;
  --bbl-gold-bold:  #8f5f14;
  --bbl-gold-soft:  #a67c2e;
  --bbl-gold-tint:  #f1e7d3;
  --bbl-gold-pale:  #f1e7d3;
  --bbl-gold-faint: rgba(176, 122, 36, 0.32);
  /* RGB triplet form of the accent, for rgba(var(--bbl-gold-rgb), a) literals
     (masthead rules, borders) that need theme-aware alpha. Light = brass. */
  --bbl-gold-rgb:   176, 122, 36;

  /* FILLED-ACCENT BUTTON PAIR (RMB-TASK-481, 2026-08-27) — the brass pill with
     text on it: "Fire CTO", "Present a proposal", the Clients gold buttons.
     These two MUST be read together and MUST flip together.

     Why they exist rather than reusing --bbl-gold + white. A filled accent
     needs its foreground to move in the OPPOSITE direction to the fill across
     themes, and --bbl-gold moves the wrong way for a fixed foreground: it is a
     DARK brass in light mode and a BRIGHT orange in dark, so white text scored
     3.71:1 in light and 2.94:1 in dark — both under the 4.5:1 AA floor, and
     the light one is what axe reported as `color-contrast` serious on the
     Triage rows' Fire CTO button.

     The pair fixes both at once by flipping the fill as well as the text:
       light  #ffffff on --bbl-gold-bold #8f5f14  = 5.50:1
       dark   --bbl-bg #14120d on --bbl-gold #e07d33 = 6.37:1
     No single foreground on a single fill can clear AA in both themes, which
     is why this is a pair and not one more colour.

     NOT the same thing as the semantic tier's --on-accent. That role maps to
     the card cream, which is 3.55:1 on brass — it is unadopted (RMB-TASK-377)
     and would not have cleared this gate either. */
  --bbl-accent-fill:    var(--bbl-gold-bold);
  --bbl-on-accent-fill: #ffffff;

  /* Interaction-layer accents (hover text, hover borders, hover tints) — kept
     as their own vars so interactions.css hovers turn orange in dark alongside
     the base accent. Light values = the original brass hover palette. */
  --bbl-accent-hi:       #d8bf85;
  --bbl-accent-line:     #c2a35d;
  --bbl-accent-line-2:   #a98b4f;
  --bbl-accent-tint-rgb: 169, 139, 79;

  --bbl-ink:   #171410;
  --bbl-ink-2: #57534a;
  --bbl-ink-3: #8a867a;
  --bbl-ink-4: #b0ab9b;

  --bbl-line:   #e2dccb;
  --bbl-line-2: #ece7d9;

  --bbl-green: #4d7c54;
  --bbl-amber: #b5791f;
  --bbl-red:   #b0483e;

  --bbl-font-sans:         'Public Sans', system-ui, sans-serif;
  --bbl-font-display:      'Playfair Display', Georgia, serif;
  --bbl-font-display-soft: 'Playfair Display', Georgia, serif;
  --bbl-font-mono:         'IBM Plex Mono', 'SF Mono', Menlo, monospace;

  --bbl-shadow-card: 0 1px 2px rgba(23, 20, 16, 0.05), 0 10px 30px rgba(23, 20, 16, 0.05);
  --bbl-radius:    6px;
  --bbl-radius-sm: 4px;

  /* Semantic chrome surfaces — the masthead band and the header button/pill
     "face". Broken out as their own tokens so dark mode can retune them
     without touching the components that consume them. */
  --bbl-masthead: #f1ece0;
  --bbl-btn-face: rgba(23, 20, 16, 0.03);

  /* Scrollbar + text selection — retuned per theme below. */
  --bbl-scrollbar:       #d4cdbc;
  --bbl-scrollbar-hover:  #c3bba6;
  --bbl-selection: rgba(176, 122, 36, 0.20);

  /* Legacy-compat aliases — federation-remote agents (e.g. Oracle) reference
     these older var names; defined here so they resolve to Ivory values when
     an agent renders IN-SHELL (the agent's own :root only applies standalone). */
  --bbl-cloud: var(--bbl-bg);
  --bbl-white: var(--bbl-card);
  --bbl-cream: var(--bbl-gold-tint);
  --bbl-muted: var(--bbl-ink-2);
  --bbl-serif: var(--bbl-font-display);

  /* Native controls (time picker, checkbox, default scrollbar) follow this. */
  color-scheme: light;
}

/* ---------------------------------------------------------------------------
   DARK MODE — "Ivory Study, after hours".
   The same warm cream + brass system relit on a warm near-black ground
   (browns, not cold grays) so the palette still reads as ivory paper turned
   down for the evening. Activated by data-theme="dark" on <html> (set pre-paint
   from localStorage in index.html; toggled at runtime by shell/theme.js).

   The saturated brass accents (--bbl-gold / --bbl-gold-soft) are deliberately
   NOT overridden — they read on both grounds and back the SVG icon strokes that
   consume the literal token values. Only --bbl-gold-bold (text/links) brightens.
   ------------------------------------------------------------------------- */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bbl-bg:         #14120d;
  --bbl-bg-soft:    #1b1811;
  --bbl-bg-deep:    #201c14;
  --bbl-bg-handoff: #1d1912;
  --bbl-card:       #1e1a13;

  /* "navy" is the raised-fill role (buttons, pills, icon squares, stat bands),
     always paired with light content — so in dark mode it inverts to a warm
     surface that sits ABOVE the card, not below it. Navy-as-text was migrated
     to --bbl-ink so this inversion is safe. */
  --bbl-navy:        #423a29;
  --bbl-navy-soft:   #4d4432;
  --bbl-navy-medium: #574d39;
  --bbl-navy-deep:   #383021;

  /* Dark ground: lift the chat navy so it still reads blue over the warm-brown
     surface (not a muddy near-black). */
  --bbl-chat-mine:   #3d5382;

  /* Scratchpad pens on the dark ground: the light-mode values are near-black
     here and would vanish, so both lift to legible tints that KEEP the
     grey-vs-navy distinction — the whole point of the two colours. */
  --bbl-pen-maxim:      #b6b2aa;
  --bbl-pen-jackson:    #7fa8d4;
  --bbl-pen-maxim-bg:   rgba(182, 178, 170, 0.07);
  --bbl-pen-jackson-bg: rgba(127, 168, 212, 0.09);

  /* Dark mode trades the ivory brass for a warm ORANGE accent — it contrasts
     harder against the warm-brown ground and reads more vividly than gold did.
     The base drives the agent-medallion rings/glyphs (via currentColor) and
     every gold fill/border; -bold is the brighter text/link/active tone. */
  --bbl-gold:       #e07d33;
  --bbl-gold-bold:  #f39a4d;
  --bbl-gold-soft:  #cf7330;
  --bbl-gold-tint:  #2c1c0f;
  --bbl-gold-pale:  #2c1c0f;
  --bbl-gold-faint: rgba(224, 125, 51, 0.30);
  --bbl-gold-rgb:   224, 125, 51;

  /* The filled-accent pair, flipped (see the light block for the full note).
     Dark's accent is a BRIGHT orange, so the fill stays at the base tone and
     the text goes to the page ground: #14120d on #e07d33 = 6.37:1. Taking
     --bbl-gold-bold here instead would make the fill brighter still and put
     white at 2.20:1 — worse than the bug this replaces. */
  --bbl-accent-fill:    var(--bbl-gold);
  --bbl-on-accent-fill: var(--bbl-bg);

  --bbl-accent-hi:       #f6a860;
  --bbl-accent-line:     #e5893f;
  --bbl-accent-line-2:   #cf7734;
  --bbl-accent-tint-rgb: 224, 125, 51;

  --bbl-ink:   #f2ede1;
  --bbl-ink-2: #c4bca9;
  --bbl-ink-3: #948c7b;
  --bbl-ink-4: #6c6555;

  --bbl-line:   #322c20;
  --bbl-line-2: #2a251b;

  --bbl-green: #6bb07a;
  --bbl-amber: #d4972f;
  --bbl-red:   #d9695f;

  --bbl-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.5);

  --bbl-masthead: #1a1610;
  --bbl-btn-face: rgba(255, 255, 255, 0.05);

  --bbl-scrollbar:       #3a3428;
  --bbl-scrollbar-hover:  #4a4334;
  --bbl-selection: rgba(215, 165, 63, 0.28);
}

/* ---------------------------------------------------------------------------
   SEMANTIC TIER — roles, not colour identities (RMB-TASK-378)
   ---------------------------------------------------------------------------
   Everything above this line names a COLOUR: --bbl-gold, --bbl-navy, --bbl-bg,
   --bbl-card. Components therefore consume identities rather than roles, and
   two things follow. A re-theme means renaming meaning rather than changing
   values. And the dark theme already fights its own vocabulary — "navy" here
   denotes a near-black warm neutral, not a blue, which is why --bbl-chat-mine
   had to be introduced above just to get an actually-blue bubble.

   This tier is the role layer, mapped onto the EXISTING primitives. It is
   PURELY ADDITIVE: no declaration above changed, and nothing consumes these
   yet, so this commit cannot move a pixel. Migrating components onto them is
   the separate, still-undecided adoption question (RMB-TASK-377).

   WHY THERE IS NO DARK COUNTERPART, AND WHY THAT IS NOT AN OVERSIGHT.
   These resolve through var() at use time, not at definition time. Dark mode
   overrides the PRIMITIVES on the same element (:root[data-theme="dark"]), so
   --surface re-resolves to the dark --bbl-card automatically. Redefining the
   semantic names per theme would be a second place to keep in sync and a
   second place to get it wrong.

   ON- PAIRS. A surface gets an on- pair: the foreground guaranteed to be
   legible against it. --text-primary / --text-secondary are themselves
   foreground roles and --border-hairline is a line, so none of the three takes
   an on- pair — inventing --on-text-primary would name nothing.
   ------------------------------------------------------------------------- */
:root {
  /* Grounds. --surface is the page; --surface-raised is anything sitting on
     top of it (cards, panels, popovers). */
  --surface:            var(--bbl-bg);
  --on-surface:         var(--bbl-ink);
  --surface-raised:     var(--bbl-card);
  --on-surface-raised:  var(--bbl-ink);

  /* Foreground. Primary is body copy and headings; secondary is the supporting
     register — captions, metadata, timestamps. */
  --text-primary:    var(--bbl-ink);
  --text-secondary:  var(--bbl-ink-2);

  /* Accent. --on-accent is what reads on a FILLED accent (a brass button), and
     is deliberately the card cream rather than pure white so it stays inside
     the palette in both themes. */
  --accent:     var(--bbl-gold);
  --on-accent:  var(--bbl-card);

  /* The 1px rule between regions. */
  --border-hairline: var(--bbl-line);
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  background: var(--bbl-bg);
  color: var(--bbl-ink);
  font-family: var(--bbl-font-sans);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--bbl-selection); }
* { scrollbar-color: var(--bbl-scrollbar) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--bbl-scrollbar); border-radius: 999px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--bbl-scrollbar-hover); border: 3px solid transparent; background-clip: content-box; }

/* Keyboard up: the keyboard COVERS the home indicator, so the safe-area
   allowance is no longer protecting anything — it just becomes dead space
   between the message box and the top of the keys. Zero it while the keyboard
   is open; useKeyboardInset() puts this class on <html>. */
:root.bbl-kb-open {
  --bbl-safe-bottom: 0px;
}
/* Atelier profile — token overrides (Stage 1 of the 2026-09 re-skin).
   Source of truth for the values: the approved mockup (cc-full-template.html,
   the locked "G / Blanc" profile) — pure white ground, #15160f ink scale,
   #b08a3c/#87671f gold, #e9e9e4/#d8d9d1 hairlines, white cards, the profile
   shadow, Bodoni/Didot display type over a Segoe UI text face.

   EVERY rule in this file is scoped under :root[data-ui="atelier"] (stamped
   pre-paint by index.html). With the flag off this file is inert and the
   classic Ivory Study palette in tokens.css is untouched — that is the whole
   reversibility contract.

   LOAD ORDER IS LOAD-BEARING: this file is linked AFTER tokens.css in
   index.html. :root[data-ui="atelier"] ties tokens.css's dark block
   :root[data-theme="dark"] on specificity, so source order is what makes the
   Atelier values win. Deliberate consequence: the Atelier profile is a
   light-only design in Stage 1 — with atelier on, the dark-mode toggle has no
   effect (the profile overrides the same custom properties the dark block
   sets). Stage 2+ owns an after-hours variant if one is ever wanted. */

:root[data-ui="atelier"] {
  color-scheme: light;

  /* Grounds — pure white page, white cards, the mockup "wash" for soft fills. */
  --bbl-bg:         #ffffff;
  --bbl-bg-soft:    #f8f8f6;
  --bbl-bg-deep:    #f1f1ed;
  --bbl-bg-handoff: #f8f8f6;
  --bbl-card:       #ffffff;

  /* "navy" is the raised dark fill role (primary buttons, pills). The mockup's
     primary control fill is the ink itself. */
  --bbl-navy:        #15160f;
  --bbl-navy-soft:   #26271e;
  --bbl-navy-medium: #33342a;
  --bbl-navy-deep:   #0b0c07;

  /* Ink scale. */
  --bbl-ink:   #15160f;
  --bbl-ink-2: #54574c;
  --bbl-ink-3: #989b8f;
  --bbl-ink-4: #b6b8ae;

  /* Hairlines: --bbl-line is the default rule, --bbl-line-strong (new,
     atelier-only) is the mockup's control-border weight. --bbl-line-2 stays
     the softer of the pair. */
  --bbl-line:        #e9e9e4;
  --bbl-line-2:      #f0f0ec;
  --bbl-line-strong: #d8d9d1;

  /* Gold: #b08a3c strokes/fills, #87671f for text and links (5.25:1 on white;
     white on #87671f is 5.25:1 too, so the filled-accent pair below holds AA). */
  --bbl-gold:       #b08a3c;
  --bbl-gold-bold:  #87671f;
  --bbl-gold-soft:  #b08a3c;
  --bbl-gold-tint:  #f4efe3;
  --bbl-gold-pale:  #f4efe3;
  --bbl-gold-faint: rgba(176, 138, 60, 0.32);
  --bbl-gold-rgb:   176, 138, 60;

  /* --bbl-accent-fill / --bbl-on-accent-fill need no override: they resolve
     through --bbl-gold-bold / #ffffff, which the values above keep at AA. */

  --bbl-accent-hi:       #c9a55f;
  --bbl-accent-line:     #b08a3c;
  --bbl-accent-line-2:   #87671f;
  --bbl-accent-tint-rgb: 176, 138, 60;

  /* Status hues (mockup --green / --coral; amber inherits the classic value,
     which already reads on white). */
  --bbl-green: #2c7a57;
  --bbl-red:   #c4552e;

  /* VARIATION 3 "Bento" (locked by Maxim 2026-09-04) — flat, dense cards:
     body.v3 .panel/.ccard carry box-shadow:none and 8px radii in the mockup.
     Cards therefore go FLAT here; floating layers (dropdowns, popovers) keep
     the profile shadow via --at-shadow-pop below. */
  --bbl-shadow-card: none;
  --at-shadow-pop: 0 1px 2px rgba(21, 22, 15, 0.04), 0 18px 44px rgba(21, 22, 15, 0.07);

  /* v3 radii: 8px cards/panels, 6px small controls. */
  --bbl-radius:    8px;
  --bbl-radius-sm: 6px;

  /* Chrome surfaces: the masthead band and button faces sit ON the white
     ground, not tinted panels of their own. */
  --bbl-masthead: #ffffff;
  --bbl-btn-face: #ffffff;

  --bbl-scrollbar:       #d8d9d1;
  --bbl-scrollbar-hover: #c6c7bf;
  --bbl-selection: rgba(176, 138, 60, 0.18);

  /* Type. Bodoni/Didot display; Cinzel stays reserved for the wordmark (the
     lockup styles carry it inline, same as classic). tokens.js resolves the
     bblFont constants through these custom properties. */
  --bbl-font-display:      'Bodoni MT', 'Didot', Constantia, Georgia, serif;
  --bbl-font-display-soft: 'Bodoni MT', 'Didot', Constantia, Georgia, serif;
  --bbl-font-sans:         'Segoe UI', Corbel, 'Avenir Next', system-ui, sans-serif;
  --bbl-font-mono:         'Cascadia Mono', Consolas, 'SF Mono', monospace;
}

/* ---------------------------------------------------------------------------
   Narrow component corrections — places where a component hardcodes a colour
   tuned to the cream ground and the pure white ground breaks it. Kept HERE
   (not in the components) so the classic files stay untouched; each override
   is scoped under [data-ui="atelier"].
   ------------------------------------------------------------------------- */

/* The masthead's brass rules were rgba over cream; on white the 0.32-alpha
   lower rule of the double rule nearly vanishes. The gold-rgb var override
   above already retunes them — no further correction needed today. Add new
   corrections below this line as they are found. */

/* index.html's pre-mount loader stamps Playfair in a font shorthand literal
   (it renders before any bundle, so it cannot read tokens.js). Swap just the
   face under the profile. */
:root[data-ui="atelier"] #root:empty::before {
  font-family: 'Bodoni MT', 'Didot', Constantia, Georgia, serif;
}
/* Atelier profile — component styles (Stage 1: arrival veil + masthead).
   Values copied faithfully from the approved mockup (cc-full-template.html).
   EVERYTHING here is scoped under [data-ui="atelier"]; keyframe names are
   at-prefixed (keyframes cannot be attribute-scoped, so the prefix is the
   collision guard). With the flag off, no element carries these classes and
   no rule can match — the classic UI is untouched. */

/* ================= THE ARRIVAL — "The Composition" =================
   Mark rises, rule draws, page lifts in. Timings locked in the mockup:
   veil-out at 1.6s, mark-in .9s@.05s, word .7s@.5s, rule .8s@.35s. */
:root[data-ui="atelier"] .at-veil {
  position: fixed; inset: 0; z-index: 80; display: grid; place-items: center;
  background: transparent; pointer-events: none;
}
:root[data-ui="atelier"] .at-veil-bg { position: absolute; inset: 0; background: var(--bbl-bg); }
:root[data-ui="atelier"] .at-veil-stage { position: relative; display: grid; place-items: center; gap: 16px; }
:root[data-ui="atelier"] .at-veil img { display: block; width: 74px; height: auto; opacity: 0; }
:root[data-ui="atelier"] .at-veil-word {
  font-family: 'Cinzel', Constantia, Georgia, serif; font-size: 13px;
  letter-spacing: .5em; text-transform: uppercase; color: var(--bbl-ink);
  opacity: 0; padding-left: .5em;
}
:root[data-ui="atelier"] .at-veil-rule {
  width: 0; height: 1px; background: var(--bbl-gold);
  /* The drawn rule's final length — the keyframe reads this, so the phone
     block below can shorten the rule without a second keyframe. */
  --at-rule-w: 150px;
}
:root[data-ui="atelier"] .at-run .at-veil-bg { animation: at-veil-out .6s ease 1.6s forwards; }
:root[data-ui="atelier"] .at-run .at-veil-stage { animation: at-veil-out .5s ease 1.6s forwards; }
:root[data-ui="atelier"] .at-run img { animation: at-mark-in .9s cubic-bezier(.2,.7,.2,1) .05s forwards; }
:root[data-ui="atelier"] .at-run .at-veil-word { animation: at-mark-in .7s ease .5s forwards; }
:root[data-ui="atelier"] .at-run .at-veil-rule { animation: at-rule-out .8s cubic-bezier(.4,0,.2,1) .35s forwards; }
@keyframes at-mark-in { from { opacity: 0; transform: translateY(8px) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes at-rule-out { to { width: var(--at-rule-w, 150px); } }
@keyframes at-veil-out { to { opacity: 0; visibility: hidden; } }
/* A steeper rise for the mark on phones (the desktop 8px reads as nothing at
   arm's length); same curve, more travel. */
@keyframes at-mark-in-m { from { opacity: 0; transform: translateY(14px) scale(.9); } to { opacity: 1; transform: none; } }

/* ---- The arrival on PHONES (2026-09-05, owner's mobile pass) ----
   The composition is retuned for the small screen rather than scaled down:
   the mark and rule size against the viewport, the wordmark tightens a
   notch, and the stage is optically lifted above true center — which also
   masks the downward shift when the browser chrome collapses mid-animation
   (a fixed inset:0 layer grows at the BOTTOM edge when the address bar
   hides, so height added below a lifted stage moves it less). The micro
   animations get slightly shorter travel-matched durations so the rise
   feels deliberate at this scale, but every BEAT the chime keys on is
   untouched: word at .5s, veil-out at 1.6s, exit note 1680ms. */
@media (max-width: 700px) {
  :root[data-ui="atelier"] .at-veil {
    padding-bottom: calc(8vh + env(safe-area-inset-bottom));
    box-sizing: border-box;
  }
  :root[data-ui="atelier"] .at-veil-stage { gap: 14px; }
  :root[data-ui="atelier"] .at-veil img { width: clamp(56px, 17vw, 70px); }
  :root[data-ui="atelier"] .at-veil-word {
    font-size: clamp(10.5px, 3.1vw, 12px);
    letter-spacing: .42em;
    padding-left: .42em;
  }
  :root[data-ui="atelier"] .at-veil-rule { --at-rule-w: clamp(96px, 34vw, 140px); }
  :root[data-ui="atelier"] .at-run img {
    animation-name: at-mark-in-m;
    animation-duration: .8s;
  }
  :root[data-ui="atelier"] .at-run .at-veil-word { animation-duration: .6s; }
  :root[data-ui="atelier"] .at-run .at-veil-rule { animation-duration: .7s; }
}

/* ================= MASTHEAD ================= */
/* Fluid frame — fills the viewport with a readable ceiling; no dead margins. */
:root[data-ui="atelier"] .at-headwrap {
  position: relative;
  background: var(--bbl-bg);
  border-bottom: 1px solid var(--bbl-line);
  flex-shrink: 0;
  /* Its own stacking context ABOVE the page content, so the nav dropdowns
     always paint in front of what follows. */
  z-index: 50;
}
:root[data-ui="atelier"] .at-frame {
  max-width: 1720px; margin: 0 auto; padding: 0 clamp(16px, 3vw, 48px);
}
:root[data-ui="atelier"] .at-header {
  display: flex; align-items: center; gap: 26px; padding: 18px 0 16px;
}

/* Compact single-row lockup: monogram + Cinzel wordmark. */
:root[data-ui="atelier"] .at-lockup {
  display: flex; align-items: flex-end; gap: 13px; flex-shrink: 0;
  text-decoration: none; color: inherit;
  background: transparent; border: none; padding: 0; cursor: pointer;
  font: inherit; text-align: left;
}
:root[data-ui="atelier"] .at-lockup img { display: block; width: 44px; height: auto; }
:root[data-ui="atelier"] .at-wordmark {
  font-family: 'Cinzel', Constantia, Georgia, serif; font-weight: 600;
  font-size: 16px; letter-spacing: .18em; text-transform: uppercase;
  line-height: 1; padding-bottom: 2px; color: var(--bbl-ink);
}
:root[data-ui="atelier"] .at-wordmark small {
  display: block; font-family: var(--bbl-font-sans); font-weight: 600;
  font-size: 8.5px; letter-spacing: .34em; color: var(--bbl-ink-3); margin-top: 5px;
}

/* Small-caps horizontal nav with the full-label gold underline. */
:root[data-ui="atelier"] .at-nav { display: flex; gap: 2px; margin-left: 4px; }
:root[data-ui="atelier"] .at-nav a {
  position: relative; color: var(--bbl-ink-2); text-decoration: none;
  font-size: 12.5px; letter-spacing: .09em; text-transform: uppercase;
  padding: 10px 13px; transition: color .15s;
}
/* The active underline runs edge-to-edge of the tab label (a touch beyond),
   never narrower than the word. */
:root[data-ui="atelier"] .at-nav a::after {
  content: ''; position: absolute; left: 9px; right: 9px; bottom: 4px;
  height: 2px; background: var(--bbl-gold); border-radius: 2px;
  transform: scaleX(0); transform-origin: left;
  transition: transform .22s cubic-bezier(.2,.7,.2,1);
}
:root[data-ui="atelier"] .at-nav a:hover { color: var(--bbl-ink); }
:root[data-ui="atelier"] .at-nav a:hover::after { transform: scaleX(1); }
:root[data-ui="atelier"] .at-nav a[aria-current] { color: var(--bbl-ink); }
:root[data-ui="atelier"] .at-nav a[aria-current]::after { transform: scaleX(1); }

/* Hover dropdowns — a tab reveals its sub-pages for direct navigation. */
:root[data-ui="atelier"] .at-navitem { position: relative; }
/* Permanent invisible hover extension: during the .15s open delay the pointer
   often drifts DOWN into the 10px gap before the panel exists, killing :hover
   — this strip keeps .at-navitem:hover alive across the gap. */
:root[data-ui="atelier"] .at-navitem::after {
  content: ''; position: absolute; top: 100%; left: 0; right: 0; height: 14px;
}
:root[data-ui="atelier"] .at-drop {
  position: absolute; top: calc(100% + 10px); left: 6px; min-width: 176px;
  background: var(--bbl-bg); border: 1px solid var(--bbl-line);
  border-radius: 12px; box-shadow: var(--at-shadow-pop); padding: 7px; z-index: 60;
  opacity: 0; visibility: hidden; transform: translateY(7px);
  transition: opacity .18s ease, transform .18s cubic-bezier(.2,.7,.2,1), visibility .18s;
}
/* Invisible bridge so the pointer can cross the gap without closing it. */
:root[data-ui="atelier"] .at-drop::before {
  content: ''; position: absolute; top: -12px; left: 0; right: 0; height: 12px;
}
/* Keyboard focus (focus-visible) opens a dropdown; a mouse CLICK must not pin
   one open — that's how two could show at once. */
:root[data-ui="atelier"] .at-navitem:hover .at-drop,
:root[data-ui="atelier"] .at-navitem:has(:focus-visible) .at-drop {
  opacity: 1; visibility: visible; transform: none; transition-delay: .15s;
}
:root[data-ui="atelier"] .at-drop a {
  display: block; padding: 9px 13px; font-size: 12.5px; letter-spacing: .02em;
  text-transform: none; color: var(--bbl-ink-2); border-radius: 7px; white-space: nowrap;
}
:root[data-ui="atelier"] .at-drop a::after { display: none; }
:root[data-ui="atelier"] .at-drop a:hover { background: var(--bbl-bg-soft); color: var(--bbl-ink); }
/* A clicked navitem's dropdown vanishes at once; hover re-arms on re-entry. */
:root[data-ui="atelier"] .at-navitem.at-drop-lock .at-drop {
  opacity: 0 !important; visibility: hidden !important; transition: none;
}
/* Agents dropdown rows — small engraved mark + name. */
:root[data-ui="atelier"] .at-drop a.at-aitem { display: flex; align-items: center; gap: 9px; }
:root[data-ui="atelier"] .at-drop .at-dicon { width: 22px; height: 22px; flex-shrink: 0; color: var(--bbl-gold-bold); display: inline-flex; }

/* Utility cluster: bell + gear. */
:root[data-ui="atelier"] .at-util { margin-left: auto; display: flex; align-items: center; gap: 9px; }
:root[data-ui="atelier"] .at-iconbtn {
  width: 36px; height: 36px; border: 1px solid var(--bbl-line-strong);
  background: var(--bbl-bg); border-radius: 999px; display: grid;
  place-items: center; cursor: pointer; color: var(--bbl-ink-2);
  transition: border-color .15s, color .15s, box-shadow .15s; position: relative;
}
:root[data-ui="atelier"] .at-iconbtn:hover {
  border-color: var(--bbl-gold); color: var(--bbl-ink);
  box-shadow: 0 0 0 3px rgba(176, 138, 60, .08);
}
:root[data-ui="atelier"] .at-iconbtn:focus-visible,
:root[data-ui="atelier"] .at-nav a:focus-visible,
:root[data-ui="atelier"] .at-lockup:focus-visible {
  outline: 2px solid var(--bbl-gold); outline-offset: 2px;
}
/* Unread count — a bare superscript numeral at the bell's shoulder. */
:root[data-ui="atelier"] .at-ncount {
  position: absolute; top: 1px; right: 4px; font-family: var(--bbl-font-sans);
  font-size: 10px; line-height: 1; color: var(--bbl-gold-bold); font-weight: 700;
  background: none; border: 0; padding: 0;
}

/* The masthead nav collapses on narrow windows (the phone bar + drawer keep
   serving navigation there — mobile Atelier is Stage 2). */
@media (max-width: 980px) {
  :root[data-ui="atelier"] .at-nav { display: none; }
}

/* ================= NOTICES WIRE (Home only) ================= */
/* Mockup .wire: a hairlined strip — small-caps gold label, one rotating
   message, index dots, dismiss. Rotation is JS-driven (variable line count);
   this is presentation only. */
:root[data-ui="atelier"] .at-wire {
  display: flex; align-items: center; gap: 14px;
  padding: 9px 2px 8px; border-bottom: 1px solid var(--bbl-line);
  margin-bottom: 14px;
}
:root[data-ui="atelier"] .at-wire-lbl {
  font-size: 9px; letter-spacing: .32em; text-transform: uppercase;
  color: var(--bbl-gold-bold); flex-shrink: 0; font-weight: 600;
}
:root[data-ui="atelier"] .at-wire-msg {
  flex: 1; min-width: 0; font-size: 12px; color: var(--bbl-ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
:root[data-ui="atelier"] .at-wire-idx { display: flex; gap: 5px; flex-shrink: 0; }
:root[data-ui="atelier"] .at-wire-idx i {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--bbl-line-strong, var(--bbl-line));
}
:root[data-ui="atelier"] .at-wire-idx i.on { background: var(--bbl-gold); }
:root[data-ui="atelier"] .at-wire-close {
  flex-shrink: 0; width: 20px; height: 20px; border: 1px solid var(--bbl-line);
  background: none; border-radius: 50%; color: var(--bbl-ink-3);
  font-size: 10px; line-height: 1; cursor: pointer;
  display: grid; place-items: center; padding: 0;
  transition: color .15s, border-color .15s;
}
:root[data-ui="atelier"] .at-wire-close:hover {
  color: var(--bbl-ink); border-color: var(--bbl-line-strong, var(--bbl-line));
}
:root[data-ui="atelier"] .at-wire-close:focus-visible {
  outline: 2px solid var(--bbl-gold); outline-offset: 2px;
}

/* ================= THE AGENCY ROSTER — forest band ================= */
/* Mockup .band/.court5/.rmed: the roster sits on a deep forest ground, each
   agent a free-standing engraved mark over a serif name. Hover: soft tint,
   3px lift, glow on the mark. */
:root[data-ui="atelier"] .at-rmed {
  transition: background .25s, transform .25s;
}
:root[data-ui="atelier"] .at-rmed:hover {
  background: rgba(234, 240, 234, 0.06);
  transform: translateY(-3px);
}
:root[data-ui="atelier"] .at-rmed .at-rmed-mark { transition: filter .3s; }
:root[data-ui="atelier"] .at-rmed:hover .at-rmed-mark {
  filter: drop-shadow(0 0 12px rgba(234, 240, 234, 0.35));
}
:root[data-ui="atelier"] .at-rmed:focus-visible {
  outline: 2px solid var(--bbl-gold); outline-offset: 2px;
}

/* ================= INTERIOR IDIOM LAYER (parity pass 2) =================
   The preview's interior vocabulary applied over the inline-styled panels
   through their STABLE hooks (testids, the week-cell classes, element
   selectors). !important is deliberate: these fight inline styles, and this
   is a skin layer confined to this file and this profile — classic sessions
   never carry data-ui, so none of it can leak. */

/* v3 .panel frame for the home panels (trio, pipeline, week). */
:root[data-ui="atelier"] [data-testid="attention-center-panel"],
:root[data-ui="atelier"] [data-testid="home-cto-pipeline"],
:root[data-ui="atelier"] [data-testid="overview-today-time"],
:root[data-ui="atelier"] [data-testid="overview-dev-log"],
:root[data-ui="atelier"] [data-testid="home-clients-panel"],
:root[data-ui="atelier"] [data-testid="week-calendar-panel"] {
  border: 1px solid var(--bbl-line) !important;
  border-radius: 8px !important;
  background: var(--bbl-card) !important;
  box-shadow: none !important;
}

/* The attention panel's head is SectionTitle — div > div > h2 — so the `> h2`
   below never reached it, and it rendered as a 20px uppercase serif jammed
   against the frame's top edge, with a SECOND black-bordered box inside the
   frame (found in the 2026-09-10 phone audit). The head gets the frame's
   padding, and the inner card stands down: the frame is the one border. */
:root[data-ui="atelier"] [data-testid="attention-center-panel"] > div:first-child {
  padding: 14px 18px 0 !important;
  margin-bottom: 6px !important;
}
:root[data-ui="atelier"] [data-testid="attention-center-panel"] > section {
  border: none !important;
  box-shadow: none !important;
  background: transparent !important;
}

/* .mh — the quiet small-caps panel head (trio + pipeline). */
:root[data-ui="atelier"] [data-testid="attention-center-panel"] > div:first-child h2,
:root[data-ui="atelier"] [data-testid="attention-center-panel"] > h2,
:root[data-ui="atelier"] [data-testid="attention-center-panel"] > h3,
:root[data-ui="atelier"] [data-testid="home-cto-pipeline"] h2,
:root[data-ui="atelier"] [data-testid="home-cto-pipeline"] h3,
:root[data-ui="atelier"] [data-testid="overview-today-time"] h2,
:root[data-ui="atelier"] [data-testid="overview-today-time"] h3,
:root[data-ui="atelier"] [data-testid="overview-dev-log"] h2,
:root[data-ui="atelier"] [data-testid="overview-dev-log"] h3,
:root[data-ui="atelier"] [data-testid="home-clients-panel"] h2,
:root[data-ui="atelier"] [data-testid="home-clients-panel"] h3 {
  font-family: var(--bbl-font-sans) !important;
  font-size: 10px !important;
  letter-spacing: .26em !important;
  text-transform: uppercase !important;
  color: var(--bbl-ink-3) !important;
  font-weight: 700 !important;
}

/* .tbl — every data table reads as the preview's table (the repo's own rule:
   "every table in this Command Center reads as one design"). */
:root[data-ui="atelier"] main table { border-collapse: collapse !important; }
:root[data-ui="atelier"] main table th {
  text-align: left;
  font-size: 9.5px !important;
  letter-spacing: .22em !important;
  text-transform: uppercase !important;
  /* ink-2, NOT ink-3 (fixed 2026-09-07 — WCAG AA).
     Measured in the browser on the live palette:
         ink-3 on bg-soft = 2.66:1   FAILS AA (needs 4.5:1 at this size)
         ink-2 on bg-soft = 6.94:1   passes
     The idiom layer had quietly taken EVERY table header in the Command
     Center from a comfortable pass to a fail — it was written for the
     preview's look and the contrast was never measured. axe caught it on
     /helpdesk/triage, but the selector is `main table th`, so it was every
     table on every page. ink-2 keeps the head quiet and muted; it is still
     obviously a header rather than body text, and it is now readable. */
  color: var(--bbl-ink-2) !important;
  font-weight: 700 !important;
  padding: 10px 12px !important;
  border-bottom: 1px solid var(--bbl-line-strong, var(--bbl-line)) !important;
  background: transparent !important;
}
:root[data-ui="atelier"] main table td {
  padding: 12px !important;
  border-bottom: 1px solid var(--bbl-line) !important;
  background: transparent !important;
}
/* PHONE: the head's 9.5px is under the 11px floor every page and agent keeps
   on a phone (2026-09-10 prod audit). Because the rule above is !important and
   reaches every `main table`, an agent could not lift its own headers from
   inline styles — the CFO had to add a stylesheet of its own to get out from
   under it, and every other agent's tables stayed at 9.5px. Same letterspaced
   caps one size up, with the tracking eased so a column does not widen;
   desktop keeps the preview's 9.5px. */
@media (max-width: 700px) {
  :root[data-ui="atelier"] main table th {
    font-size: 11px !important;
    letter-spacing: .16em !important;
  }
}
:root[data-ui="atelier"] main table tr:last-child td { border-bottom: 0 !important; }

/* .pinput — every page-level search input becomes the round pill. */
:root[data-ui="atelier"] main input[type="search"] {
  border-radius: 999px !important;
  border: 1px solid var(--bbl-line-strong, var(--bbl-line)) !important;
  padding: 8px 15px !important;
  background: var(--bbl-bg) !important;
}
:root[data-ui="atelier"] main input[type="search"]:focus {
  outline: none;
  border-color: var(--bbl-gold) !important;
  box-shadow: 0 0 0 3px rgba(176, 138, 60, .1) !important;
}

/* .log/.lhead — the Records dev-log accordion: hairline rows, mono stamp. */
:root[data-ui="atelier"] [data-testid="dev-log-row"] {
  border: 0 !important;
  border-bottom: 1px solid var(--bbl-line) !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
:root[data-ui="atelier"] [data-testid="dev-log-time"] {
  font-family: var(--bbl-font-mono) !important;
  font-size: 10px !important;
  letter-spacing: .08em !important;
  color: var(--bbl-ink-3) !important;
}
:root[data-ui="atelier"] [data-testid="dev-log-headline"] { font-size: 13.5px !important; }
:root[data-ui="atelier"] [data-testid="dev-log-body"] {
  color: var(--bbl-ink-2) !important;
  font-size: 12.5px !important;
}

/* .week cells — white grounds, wash on today. */
:root[data-ui="atelier"] .bbl-week-day { background: var(--bbl-bg) !important; }
:root[data-ui="atelier"] .bbl-week-day.is-today { background: var(--bbl-bg-soft) !important; }

/* ================= HERO ACTION PILLS (mockup .act) ================= */
:root[data-ui="atelier"] .at-act {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--bbl-line-strong, var(--bbl-line));
  background: var(--bbl-bg); border-radius: 999px; padding: 8px 16px;
  font-size: 12.5px; font-weight: 600; color: var(--bbl-ink); cursor: pointer;
  font-family: var(--bbl-font-sans);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
:root[data-ui="atelier"] .at-act:hover {
  border-color: var(--bbl-gold);
  box-shadow: 0 0 0 3px rgba(176, 138, 60, .08);
  transform: translateY(-1px);
}
:root[data-ui="atelier"] .at-act svg { color: var(--bbl-gold); }
:root[data-ui="atelier"] .at-act.at-act-primary {
  background: var(--bbl-ink); border-color: var(--bbl-ink); color: #fff;
}
:root[data-ui="atelier"] .at-act.at-act-primary:hover {
  box-shadow: 0 4px 14px rgba(21, 22, 15, .25);
}
:root[data-ui="atelier"] .at-act.at-act-primary svg { color: #fff; }
:root[data-ui="atelier"] .at-act:focus-visible {
  outline: 2px solid var(--bbl-gold); outline-offset: 2px;
}

/* The stat band's .figures hover (cells are buttons carrying at-fig). */
:root[data-ui="atelier"] .at-fig { transition: background .18s; }
:root[data-ui="atelier"] .at-fig:hover { background: var(--bbl-bg-soft) !important; }

/* ================= SEARCH OVERLAY (⌘K) ================= */
/* Mockup #searchov/.spanel/.sgroup/.srow. */
:root[data-ui="atelier"] .at-scrim {
  position: absolute; inset: 0; background: rgba(21, 22, 15, 0.34);
  backdrop-filter: blur(2px);
}
:root[data-ui="atelier"] .at-searchov {
  position: fixed; inset: 0; z-index: 85;
}
:root[data-ui="atelier"] .at-spanel {
  position: relative; margin: 11vh auto 0; width: min(580px, 92vw);
  background: var(--bbl-bg); border: 1px solid var(--bbl-line);
  border-radius: 16px; padding: 10px; box-sizing: border-box;
  max-height: 70vh; overflow: auto;
  box-shadow: 0 2px 6px rgba(21, 22, 15, 0.06), 0 34px 80px rgba(21, 22, 15, 0.22);
}
:root[data-ui="atelier"] .at-sinput {
  width: 100%; box-sizing: border-box; border: 0;
  border-bottom: 1px solid var(--bbl-line); border-radius: 0; padding: 14px 12px;
  font-family: var(--bbl-font-sans); font-size: 15px; color: var(--bbl-ink);
  background: transparent;
}
:root[data-ui="atelier"] .at-sinput:focus { outline: none; border-bottom-color: var(--bbl-gold); }
:root[data-ui="atelier"] .at-sgroup {
  font-size: 9px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--bbl-gold-bold); font-weight: 700; padding: 14px 12px 5px;
}
:root[data-ui="atelier"] .at-srow {
  display: block; width: 100%; text-align: left; padding: 9px 12px;
  border-radius: 9px; border: none; background: transparent; cursor: pointer;
  font-family: var(--bbl-font-sans); color: inherit;
}
:root[data-ui="atelier"] .at-srow:hover,
:root[data-ui="atelier"] .at-srow:focus-visible { background: var(--bbl-bg-soft); }
:root[data-ui="atelier"] .at-srow b { display: block; font-size: 13px; font-weight: 600; color: var(--bbl-ink); }
:root[data-ui="atelier"] .at-srow span { font-size: 11px; color: var(--bbl-ink-3); }

/* The masthead search pill (mockup .search). */
:root[data-ui="atelier"] .at-search {
  display: flex; align-items: center; gap: 9px;
  border: 1px solid var(--bbl-line-strong, var(--bbl-line));
  border-radius: 999px; padding: 8px 15px; color: var(--bbl-ink-3);
  font-size: 12.5px; min-width: 190px; background: var(--bbl-bg);
  transition: border-color .15s, box-shadow .15s; cursor: text;
  font-family: var(--bbl-font-sans);
}
:root[data-ui="atelier"] .at-search:hover {
  border-color: var(--bbl-gold); box-shadow: 0 0 0 3px rgba(176, 138, 60, .08);
}
:root[data-ui="atelier"] .at-search kbd {
  margin-left: auto; font-family: var(--bbl-font-mono); font-size: 10px;
  border: 1px solid var(--bbl-line); border-radius: 4px; padding: 1px 5px;
}
@media (max-width: 1240px) {
  :root[data-ui="atelier"] .at-search { display: none; }
}

/* ================= PHONE BAR + DRAWER (Stage 2c) ================= */
/* Mockup mobile .topbar / #drawer. */
:root[data-ui="atelier"] .at-mbar {
  display: flex; align-items: center; gap: 11px;
  padding: 12px 16px; padding-top: calc(12px + env(safe-area-inset-top));
  background: var(--bbl-bg); border-bottom: 1px solid var(--bbl-line);
  position: relative; z-index: 40; flex-shrink: 0;
}
:root[data-ui="atelier"] .at-mbar-home {
  flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center;
  gap: 8px; background: transparent; border: none; padding: 0; cursor: pointer;
  /* The full bar height, not the 25px of its wordmark (2026-09-10 phone
     audit): the go-home target is the whole strip between the two buttons.
     Transparent, so nothing visible moves. */
  align-self: stretch;
}
:root[data-ui="atelier"] .at-mbar-home img { width: 26px; height: auto; display: block; }
:root[data-ui="atelier"] .at-mbar-word {
  font-family: 'Cinzel', Constantia, Georgia, serif; font-weight: 600;
  font-size: 11px; letter-spacing: .24em; text-transform: uppercase;
  padding-left: .24em; color: var(--bbl-ink); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
:root[data-ui="atelier"] .at-drawer {
  position: fixed; inset: 0; z-index: 70;
  visibility: hidden; transition: visibility 0s .32s;
}
:root[data-ui="atelier"] .at-drawer.at-open { visibility: visible; transition-delay: 0s; }
/* A CLOSING drawer stays visible for the .32s its panel takes to slide out (the
   visibility delay above) — and until 2026-09-10 its now-transparent scrim sat
   over the whole page for that .32s and ate the next tap or swipe. Found by the
   swipe spec: a touch on the page right after closing the menu landed on the
   invisible scrim. It stops taking input the moment it starts closing. */
:root[data-ui="atelier"] .at-drawer:not(.at-open) { pointer-events: none; }
:root[data-ui="atelier"] .at-drawer .at-scrim { opacity: 0; transition: opacity .28s; }
:root[data-ui="atelier"] .at-drawer.at-open .at-scrim { opacity: 1; }
:root[data-ui="atelier"] .at-dpanel {
  position: absolute; top: 0; bottom: 0; left: 0; width: min(292px, 82vw);
  background: var(--bbl-bg); border-right: 1px solid var(--bbl-line);
  padding: calc(16px + env(safe-area-inset-top)) 12px calc(16px + env(safe-area-inset-bottom));
  overflow-y: auto; box-sizing: border-box;
  transform: translateX(-102%); transition: transform .32s cubic-bezier(.2,.7,.2,1);
}
:root[data-ui="atelier"] .at-drawer.at-open .at-dpanel { transform: none; }
:root[data-ui="atelier"] .at-dhead {
  display: flex; align-items: center; gap: 10px;
  padding: 0 8px 16px; border-bottom: 1px solid var(--bbl-line); margin-bottom: 10px;
}
:root[data-ui="atelier"] .at-dhead img { width: 28px; height: auto; display: block; }
:root[data-ui="atelier"] .at-dhead span {
  font-family: 'Cinzel', Constantia, Georgia, serif; font-size: 11px;
  letter-spacing: .22em; text-transform: uppercase; color: var(--bbl-ink);
  flex: 1; min-width: 0;
}
:root[data-ui="atelier"] .at-dclose { width: 30px; height: 30px; font-size: 11px; }
:root[data-ui="atelier"] .at-dpanel nav a {
  display: block; padding: 12px 10px; font-size: 13px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--bbl-ink-2); text-decoration: none;
  border-radius: 8px;
}
:root[data-ui="atelier"] .at-dpanel nav a:hover { background: var(--bbl-bg-soft); color: var(--bbl-ink); }
:root[data-ui="atelier"] .at-dpanel nav a[aria-current] {
  color: var(--bbl-ink); box-shadow: inset 2px 0 0 var(--bbl-gold); background: var(--bbl-bg-soft);
}
:root[data-ui="atelier"] .at-dgroup {
  font-size: 8.5px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--bbl-gold-bold); font-weight: 700; padding: 16px 10px 6px;
}
:root[data-ui="atelier"] .at-dpanel nav a.at-aitem {
  display: flex; align-items: center; gap: 10px; text-transform: none;
  letter-spacing: .02em; font-size: 13.5px;
}

/* ================= BOTTOM-SHEET MODALS (phone) ================= */
/* Mockup .sheet: the modal panel rides up from the bottom edge with a grab
   handle; ModalContainer adds the classes under atelier at phone widths. */
:root[data-ui="atelier"] .at-sheet {
  animation: at-sheet-up .32s cubic-bezier(.2,.7,.2,1);
}
:root[data-ui="atelier"] .at-sheet::before {
  content: ''; display: block; width: 36px; height: 4px; border-radius: 2px;
  background: var(--bbl-line-strong, var(--bbl-line)); margin: 0 auto 14px;
}
@keyframes at-sheet-up { from { transform: translateY(105%); } to { transform: none; } }

/* ================= CLIENT BOARD CARDS (v3) ================= */
/* The mockup .ccard hover: the card lifts and throws the profile shadow.
   Hooked on the stable data-testid so the classic component needs no class
   plumbing; inert in classic because the selector is profile-scoped. The
   stage-coloured top rule the classic card carries is kept (it is data, not
   decoration). */
:root[data-ui="atelier"] [data-testid="clients-card"] {
  transition: transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s;
}
:root[data-ui="atelier"] [data-testid="clients-card"]:hover {
  transform: translateY(-4px);
  box-shadow: 0 2px 4px rgba(21, 22, 15, .05), 0 26px 56px rgba(21, 22, 15, .12);
}

/* ================= TIME BARS — .barrow idiom (parity pass 3) =================
   Mockup .barrow (Records → Time, "Where it went"): mono repo name · hairline
   bar track on the wash ground with 4px-radius fill · serif value. Hooked on
   the stable time-item-* testids; the DESKTOP ItemRow renders four direct
   spans (name | track | meta | value), which is what the nth-child selectors
   address — the phone view's stacked rows nest divs and are deliberately not
   matched (that layout is its own shape). The bar FILL's hue is kept: it
   encodes the partner identity (data, not decoration); only the track and
   radii take the mockup's values. !important fights inline styles, same as
   the pass-2 layer above. */
:root[data-ui="atelier"] [data-testid^="time-item-"] > span:nth-child(1) {
  font-family: var(--bbl-font-mono) !important;
  font-size: 12px !important;
  font-weight: 400 !important;
}
:root[data-ui="atelier"] [data-testid^="time-item-"] > span:nth-child(2) {
  background: var(--bbl-bg-soft) !important;
  border-radius: 4px !important;
}
:root[data-ui="atelier"] [data-testid^="time-item-"] > span:nth-child(2) > span {
  border-radius: 4px !important;
}
:root[data-ui="atelier"] [data-testid^="time-item-"] > span:nth-child(4) {
  font-family: var(--bbl-font-display) !important;
  font-size: 16px !important;
  color: var(--bbl-ink) !important;
}
/* The day timeline's lane labels sit above the same card's barrow rows —
   they take the mono name too so one card never mixes two name faces. */
:root[data-ui="atelier"] [data-testid^="time-day-timeline-"] > div > span:first-child {
  font-family: var(--bbl-font-mono) !important;
  font-size: 12px !important;
  font-weight: 400 !important;
}

/* ================= TASKS TOOLBAR — .ochip / .sel / .act (parity pass 3) ====
   Mockup tasks toolbar: round .ochip owner pills (gold-ringed when on),
   round .sel dropdowns, the .act pill pair on the right. The Tasks board's
   sort/group "view" controls are <select>s here exactly as in the mockup's
   tasks toolbar (the mockup's .seg segments live on Helpdesk/Time, and the
   Time page's segmented control already matches). Hooked on the stable
   testids; active state rides aria-pressed, which the component already
   sets. The owner chips drop their per-owner fill for the mockup's uniform
   gold-on-active — identity stays in the label and count. */
:root[data-ui="atelier"] [data-testid^="tasks-owner-"] {
  border: 1px solid var(--bbl-line-strong, var(--bbl-line)) !important;
  background: var(--bbl-bg) !important;
  color: var(--bbl-ink-2) !important;
  border-radius: 999px !important;
  padding: 6px 13px !important;
  transition: border-color .15s, color .15s;
}
:root[data-ui="atelier"] [data-testid^="tasks-owner-"]:hover {
  border-color: var(--bbl-gold) !important;
  color: var(--bbl-ink) !important;
}
:root[data-ui="atelier"] [data-testid^="tasks-owner-"][aria-pressed="true"] {
  border-color: var(--bbl-gold) !important;
  color: var(--bbl-ink) !important;
  box-shadow: 0 0 0 3px rgba(176, 138, 60, .08) !important;
}
:root[data-ui="atelier"] [data-testid="tasks-project-filter"],
:root[data-ui="atelier"] [data-testid="tasks-sort"],
:root[data-ui="atelier"] [data-testid="tasks-group"] {
  border: 1px solid var(--bbl-line-strong, var(--bbl-line)) !important;
  background: var(--bbl-bg) !important;
  border-radius: 999px !important;
  padding: 0 12px !important;
  font-size: 12px !important;
  color: var(--bbl-ink-2) !important;
  cursor: pointer;
}
:root[data-ui="atelier"] [data-testid="tasks-project-filter"]:hover,
:root[data-ui="atelier"] [data-testid="tasks-sort"]:hover,
:root[data-ui="atelier"] [data-testid="tasks-group"]:hover {
  border-color: var(--bbl-gold) !important;
}
:root[data-ui="atelier"] [data-testid="tasks-new"] {
  border-radius: 999px !important;
  padding: 0 16px !important;
  font-size: 12.5px !important;
  transition: box-shadow .15s;
}
:root[data-ui="atelier"] [data-testid="tasks-new"]:hover {
  box-shadow: 0 4px 14px rgba(21, 22, 15, .25);
}
:root[data-ui="atelier"] [data-testid="tasks-cto-scan"] {
  border-radius: 999px !important;
  padding: 0 16px !important;
  font-size: 12.5px !important;
  border: 1px solid var(--bbl-line-strong, var(--bbl-line)) !important;
  color: var(--bbl-ink) !important;
  background: var(--bbl-bg) !important;
  transition: border-color .15s, box-shadow .15s;
}
:root[data-ui="atelier"] [data-testid="tasks-cto-scan"]:hover {
  border-color: var(--bbl-gold) !important;
  box-shadow: 0 0 0 3px rgba(176, 138, 60, .08);
}
:root[data-ui="atelier"] [data-testid^="tasks-owner-"]:focus-visible,
:root[data-ui="atelier"] [data-testid="tasks-new"]:focus-visible,
:root[data-ui="atelier"] [data-testid="tasks-cto-scan"]:focus-visible {
  outline: 2px solid var(--bbl-gold); outline-offset: 2px;
}

/* ========== CLIENT DETAIL HEAD + CONSULTS ROWS (parity pass 3) ==========
   Mockup client detail: a small-caps gold .backlink over a serif .agenthead
   name. The back control keeps its button semantics; only the dress changes. */
:root[data-ui="atelier"] [data-testid="clients-back"] {
  border: none !important;
  background: none !important;
  padding: 0 !important;
  font-size: 10.5px !important;
  letter-spacing: .16em !important;
  text-transform: uppercase !important;
  color: var(--bbl-gold-bold) !important;
  font-weight: 600 !important;
  cursor: pointer;
}
:root[data-ui="atelier"] [data-testid="clients-back"]:hover { text-decoration: underline; }
:root[data-ui="atelier"] [data-testid="clients-back"]:focus-visible {
  outline: 2px solid var(--bbl-gold); outline-offset: 2px;
}
/* The client name right under the backlink — mockup .agenthead h1: serif,
   weight 400, oversized. The sibling selector only matches the loaded head
   (the error/loading states render no h1 in that slot). */
:root[data-ui="atelier"] [data-testid="clients-back"] + div h1 {
  font-family: var(--bbl-font-display) !important;
  font-weight: 400 !important;
  font-size: 44px !important;
  line-height: 1.05 !important;
  letter-spacing: 0 !important;
}
@media (max-width: 620px) {
  :root[data-ui="atelier"] [data-testid="clients-back"] + div h1 { font-size: 34px !important; }
}

/* Consults lobby rows — mockup .hrow: hairline-separated rows open to the
   page, no card chrome. The status pill's outline treatment is the AT fork
   in ConsultsPage.jsx (CSS cannot turn the inline fill color into a ring). */
:root[data-ui="atelier"] [data-testid="consult-row"] {
  background: transparent !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  border-bottom: 1px solid var(--bbl-line) !important;
  padding: 12px 2px !important;
  margin-bottom: 0 !important;
}
:root[data-ui="atelier"] [data-testid="consult-row"]:last-child { border-bottom: 0 !important; }
:root[data-ui="atelier"] [data-testid="consult-row"]:hover { background: var(--bbl-bg-soft) !important; }
:root[data-ui="atelier"] [data-testid="consult-row"] > div:first-child > span:first-child {
  font-family: var(--bbl-font-sans) !important;
  font-size: 13.5px !important;
  font-weight: 600 !important;
}
:root[data-ui="atelier"] [data-testid="consult-row"]:focus-visible {
  outline: 2px solid var(--bbl-gold); outline-offset: -2px;
}

/* ================= MOBILE HOME (parity pass 3) =================
   The phone home takes the mobile template's composition (MobileHome.jsx's
   atelier branch); these rules retune the shared pieces to the mobile
   template's values at phone widths. */
@media (max-width: 700px) {
  /* Hero: the mobile template's tighter scale. */
  :root[data-ui="atelier"] [data-testid="atelier-hero"] h1 {
    font-size: clamp(32px, 9.5vw, 42px) !important;
  }
  :root[data-ui="atelier"] [data-testid="atelier-hero"] > div:nth-of-type(2) {
    font-size: 16.5px !important;
  }
  /* Action pills ride one edge-to-edge scrolling row (template .actions). */
  :root[data-ui="atelier"] [data-testid="atelier-hero"] > div:last-child {
    flex-wrap: nowrap !important;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 calc(-1 * clamp(20px, 3vw, 48px));
    padding-left: clamp(20px, 3vw, 48px) !important;
    padding-right: clamp(20px, 3vw, 48px) !important;
  }
  :root[data-ui="atelier"] [data-testid="atelier-hero"] > div:last-child::-webkit-scrollbar {
    display: none;
  }
  :root[data-ui="atelier"] [data-testid="atelier-hero"] > div:last-child .at-act {
    flex-shrink: 0;
    white-space: nowrap;
  }
  /* Stat band 2-up: the wide bank-balance figure spans the full first row
     (template .fig.span2) and each stacked row gets its own hairline; the
     left-edge cells of the lower rows drop the column rule. */
  :root[data-ui="atelier"] [data-testid="stat-balance"] { grid-column: 1 / -1; }
  :root[data-ui="atelier"] [data-testid="home-digest-strip"] > :nth-child(2),
  :root[data-ui="atelier"] [data-testid="home-digest-strip"] > :nth-child(4) {
    border-left: none !important;
  }
  :root[data-ui="atelier"] [data-testid="home-digest-strip"] > :nth-child(n+2) {
    border-top: 1px solid var(--bbl-line);
  }
  /* Phone figure scale (template mobile .fig b: one 34px size for every
     cell, the wide bank string included — it owns a full row now). */
  :root[data-ui="atelier"] [data-testid="home-digest-strip"] > * > div:nth-child(2) {
    font-size: 34px !important;
    padding-top: 0 !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root[data-ui="atelier"] .at-veil { display: none; }
  :root[data-ui="atelier"] .at-nav a::after,
  :root[data-ui="atelier"] .at-drop { transition: none; }
  :root[data-ui="atelier"] [data-testid="clients-card"] { transition: none; }
  :root[data-ui="atelier"] [data-testid="clients-card"]:hover { transform: none; }
  :root[data-ui="atelier"] .at-rmed { transition: none; }
  :root[data-ui="atelier"] .at-rmed:hover { transform: none; }
  :root[data-ui="atelier"] .at-dpanel { transition: none; }
  :root[data-ui="atelier"] .at-drawer .at-scrim { transition: none; }
  /* Nothing slides here, so nothing needs the .32s visibility hold either. */
  :root[data-ui="atelier"] .at-drawer { transition: none; }
  :root[data-ui="atelier"] .at-sheet { animation: none; }
}

/* ── FORM CONTROLS (2026-09-07) ───────────────────────────────────────────
   Until now this layer styled only input[type="search"], so every OTHER
   control in the app rendered as raw browser chrome: the Helpdesk filter bar
   sat a native `mm/dd/yyyy` date field and an OS dropdown arrow next to the
   round gold-focus pills the rest of the page uses. Same page, two design
   systems.

   NO `!important` here, deliberately, and it is the opposite choice from the
   idiom rules above. Those exist to BEAT inline styles; this one exists to
   FILL IN behind them. A component that deliberately sets its own border or
   background still wins, so this cannot silently repaint a control someone
   styled on purpose — it only reaches the ones nobody ever dressed.

   `appearance: none` on <select> is the one aggressive part, because the
   native arrow cannot be restyled any other way. Checked before doing it: all
   41 selects in the UI are plain single dropdowns — none uses `multiple` or
   `size`, which are the two cases where removing native appearance would cost
   real behaviour. The chevron is an inline SVG data URI, so it needs no asset
   and follows nothing that can 404. */
:root[data-ui="atelier"] main select,
:root[data-ui="atelier"] main textarea,
:root[data-ui="atelier"] main input[type="text"],
:root[data-ui="atelier"] main input[type="email"],
:root[data-ui="atelier"] main input[type="url"],
:root[data-ui="atelier"] main input[type="tel"],
:root[data-ui="atelier"] main input[type="number"],
:root[data-ui="atelier"] main input[type="date"],
:root[data-ui="atelier"] main input[type="time"],
:root[data-ui="atelier"] main input[type="datetime-local"] {
  border: 1px solid var(--bbl-line-strong, var(--bbl-line));
  border-radius: var(--bbl-radius-sm);
  background-color: var(--bbl-bg);
  color: var(--bbl-ink);
  font-family: var(--bbl-font-sans);
  font-size: 13px;
}

/* One focus treatment for every control, replacing the OS ring. Keyboard users
   get a clearly visible target that is not colour-only — the border changes
   weight AND a halo appears. */
:root[data-ui="atelier"] main select:focus-visible,
:root[data-ui="atelier"] main textarea:focus-visible,
:root[data-ui="atelier"] main input:focus-visible {
  outline: none;
  border-color: var(--bbl-gold);
  box-shadow: 0 0 0 3px rgba(176, 138, 60, .16);
}

:root[data-ui="atelier"] main select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 28px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238a8578' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}

/* The date field's native calendar button is the last piece of OS chrome on
   the row. It cannot be replaced, only tinted — so it is tinted to the ink
   colour instead of sitting there as a blue system glyph. */
:root[data-ui="atelier"] main input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: .5;
  cursor: pointer;
}
:root[data-ui="atelier"] main input[type="date"]::-webkit-calendar-picker-indicator:hover {
  opacity: .9;
}
/* Time tab — the chart layer. Everything else on this page is inline-styled from
   tokens.js; the marks live here because they need pseudo-elements, keyframes and a
   dark-mode override that inline styles cannot express.

   COLOR: two categorical hues, one per PARTNER. Color encodes identity (whose timer
   is this), never rank — a filter that changes the row count must not repaint the
   survivors, which is exactly what the old index-keyed palette did. Projects are
   identified by their direct lane label instead.

   Both pairs were machine-checked against the card surface they sit on (light
   #fbfaf4, dark #1e1a13) for the OKLCH lightness band, the chroma floor, adjacent-
   pair CVD separation (protan/deutan/tritan) and >= 3:1 contrast. Do not hand-tune
   these values — re-run the validator. */

.time-viz {
  --time-author-1: #b07a24; /* Maxim — brass, the brand accent */
  --time-author-2: #2166a4; /* Jackson — cool blue; CVD dE 64.7 vs brass */
  --time-author-x: var(--bbl-ink-3); /* unknown author — recessive, never a 3rd hue */

  --time-grid: rgba(23, 20, 16, 0.07);
  --time-track: rgba(23, 20, 16, 0.05);
  /* The ring that separates two overlapping blocks must be the surface they sit on. */
  --time-surface: var(--bbl-card);
}

:root[data-theme='dark'] .time-viz {
  --time-author-1: #cf7330;
  --time-author-2: #3f9fd0;
  --time-grid: rgba(242, 237, 225, 0.1);
  --time-track: rgba(242, 237, 225, 0.06);
}

/* --- day timeline ---------------------------------------------------------- */

.time-lane {
  position: relative;
  height: 20px;
}

/* Recessive track behind each lane, so an empty stretch still reads as a lane. */
.time-lane::before {
  content: '';
  position: absolute;
  inset: 8px 0;
  background: var(--time-track);
  border-radius: 999px;
}

.time-block {
  position: absolute;
  top: 4px;
  bottom: 4px;
  border-radius: 4px; /* rounded data-ends */
  box-shadow: 0 0 0 2px var(--time-surface); /* 2px surface ring where blocks abut */
  cursor: pointer;
  border: none;
  padding: 0;
}

.time-block:hover,
.time-block:focus-visible {
  filter: brightness(1.08);
  outline: none;
  box-shadow:
    0 0 0 2px var(--time-surface),
    0 0 0 3px var(--bbl-ink-3);
}

/* A running block has no right edge — it is still being written. */
.time-block--running {
  border-top-right-radius: 1px;
  border-bottom-right-radius: 1px;
}

.time-gridline {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--time-grid);
}

/* --- running indicator ------------------------------------------------------ */

/* Status is never color alone: this dot always ships beside the word "running". */
.time-running-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--bbl-amber);
  animation: time-pulse 1.8s ease-in-out infinite;
}

@keyframes time-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

@media (prefers-reduced-motion: reduce) {
  .time-running-dot {
    animation: none;
  }
}

/* --- tooltip ---------------------------------------------------------------- */

.time-tooltip {
  position: fixed;
  z-index: 40;
  pointer-events: none;
  transform: translate(-50%, -110%);
  background: var(--bbl-ink);
  color: var(--bbl-card);
  border-radius: var(--bbl-radius-sm);
  padding: 6px 9px;
  font-size: 11.5px;
  line-height: 1.45;
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
}

/* --- forced-colors / print: identity must survive losing color --------------- */

@media (forced-colors: active) {
  .time-block {
    forced-color-adjust: none;
    background: ButtonText !important;
  }
  .time-block--author-2 {
    background: Highlight !important;
  }
}
/* Dev Logs page — hover/focus affordances and the rendered-mrkdwn prose.
   Colors come from the themeable --bbl-* vars so dark mode is automatic. */

.bbl-dev-log-row:hover,
.bbl-dev-log-row:focus-visible {
  background: var(--bbl-bg-soft);
}

/* The prose block is server-rendered HTML from the Slack-mrkdwn body
   (mrkdwn.js). Keep it readable and on-palette; every color is a token var. */
.bbl-dev-log-prose {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--bbl-ink);
}

.bbl-dev-log-prose p {
  margin: 0 0 10px;
}

.bbl-dev-log-prose p:last-child {
  margin-bottom: 0;
}

.bbl-dev-log-prose ul {
  margin: 0 0 10px;
  padding-left: 20px;
  list-style: disc;
}

.bbl-dev-log-prose li {
  margin: 4px 0;
}

.bbl-dev-log-prose em {
  font-style: italic;
  color: var(--bbl-ink-2);
}

.bbl-dev-log-prose strong {
  font-weight: 700;
}

.bbl-dev-log-prose code {
  font-family: 'IBM Plex Mono', 'SF Mono', Menlo, monospace;
  font-size: 12px;
  background: var(--bbl-bg-soft);
  border: 1px solid var(--bbl-line);
  border-radius: 4px;
  padding: 1px 5px;
}
/* Tasks page — hover/focus affordances for the task rows.
   Colors come from the themeable --bbl-* vars so dark mode is automatic. */

.bbl-task-id:hover,
.bbl-task-id:focus-visible {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.bbl-task-detail:hover,
.bbl-task-detail:focus-visible {
  color: var(--bbl-accent-strong, var(--bbl-gold-bold));
  text-decoration: underline;
}

.bbl-task-clear:hover,
.bbl-task-clear:focus-visible {
  text-decoration: underline;
}

/* The description cell carries overflow-wrap inline (DESC_CELL_STYLE): the row
   wrapper is display:contents at desktop width and so cannot style anything. */

/* Tile-era affordances (2026-07-26): the chevron and Send button get the same
   hover language as the rest of the board. */
.bbl-task-chevron:hover svg,
.bbl-task-chevron:focus-visible svg {
  stroke: var(--bbl-accent-strong, var(--bbl-gold-bold));
}

.bbl-task-send:hover:not(:disabled),
.bbl-task-send:focus-visible:not(:disabled) {
  border-color: var(--bbl-gold-bold);
  color: var(--bbl-gold-bold);
}

/* The clickable tag (2026-09-10). The pill is the button's only child, so the
   hover lands on the pill the partner is looking at, not on the bigger touch
   target around it. */
.bbl-task-tag:hover:not(:disabled) > span,
.bbl-task-tag:focus-visible > span {
  border-color: var(--bbl-gold-bold);
  color: var(--bbl-gold-bold);
}

.bbl-task-tag:focus-visible {
  outline: none;
}

.bbl-task-tag:focus-visible > span {
  box-shadow: 0 0 0 2px var(--bbl-gold-pale);
}

.bbl-tag-option:hover,
.bbl-tag-option:focus-visible {
  background: var(--bbl-gold-faint);
  outline: none;
}
/* The client proposal one-pager (2026-09-10).
 *
 * BBL's colored one-pager — the page Frank Benton's proposal was built on, now
 * `BBL Client Proposal Template.dotx`. Every size here is in POINTS and was
 * measured off the PDF Word produced for Frank (PyMuPDF, not by eye): a 612 x
 * 792pt Letter page, a 74pt navy masthead on a 2pt gold rule, 38pt side margins
 * (a 536pt measure), three 172.6pt cards with 9.1pt gutters, a full-bleed navy
 * band, and a footer 9pt off the foot of the page.
 *
 * WHITE PAPER IN EVERY THEME. The Command Center has a dark mode; a sheet of
 * paper does not. Every colour below is painted explicitly and nothing reads a
 * theme token, so the preview in dark mode is still the page that prints.
 *
 * Georgia and Segoe UI, exactly as the Word template. A Mac without Segoe UI
 * falls back to its system sans, which is close but not identical — the fit
 * indicator on the tab measures whatever font actually rendered. */

.bbl-onepager {
  --op-navy: #16264A;
  --op-gold: #B08A2B;
  --op-gold-pale: #E8DCC0;
  --op-ink: #1A1D24;
  --op-slate: #55607A;
  --op-mist: #A9B4CC;
  --op-card: #F6F5F1;
  --op-rule: #DAD8D0;
  --op-serif: Georgia, "Times New Roman", serif;
  --op-sans: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;

  position: relative;
  box-sizing: border-box;
  width: 8.5in;
  /* A MINIMUM, not a height: content that runs past the page grows the sheet
     instead of being clipped, so an over-long page is visibly over-long here
     and prints as two pages rather than silently losing its price. */
  min-height: 11in;
  background: #fff;
  color: var(--op-ink);
  font-family: var(--op-sans);
  font-size: 9pt;
  line-height: 13.4pt;
  text-align: left;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.bbl-onepager *,
.bbl-onepager *::before,
.bbl-onepager *::after {
  box-sizing: border-box;
}

/* The app's own h1/h2/p/ul styles must not reach the page. */
.bbl-onepager h1,
.bbl-onepager h2,
.bbl-onepager p,
.bbl-onepager ul {
  margin: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  letter-spacing: normal;
  text-transform: none;
  list-style: none;
}

/* The 32pt at the bottom is Word's bottom margin: the flow may not run into the
   footer, so the page is "full" when this padding meets the foot of the sheet. */
.op-flow { padding-bottom: 32pt; }

/* A placeholder still showing — the template's [bracketed] guidance. NOT
   dimmed: the Word template prints its brackets in the design's own colours,
   and this page must look identical to it (Maxim, 2026-09-10). The class stays
   so tests and the "placeholders left" count can find them. */
.bbl-onepager .op-ph { opacity: 1; }

/* ── masthead ─────────────────────────────────────────────────────────── */
.op-mast {
  box-sizing: content-box;   /* 74pt of navy, then the 2pt rule under it */
  display: flex;
  align-items: flex-start;
  min-height: 74pt;
  background: var(--op-navy);
  border-bottom: 2pt solid var(--op-gold);
}
.op-crest {
  flex: none;
  width: 42pt;
  height: auto;
  margin: 14pt 0 0 37.6pt;
}
.op-mast-text {
  flex: 1;
  min-width: 0;
  padding: 13.9pt 38pt 8pt 14.4pt;
}
.op-title {
  font-family: var(--op-serif);
  font-weight: 700;
  font-size: 21pt;
  line-height: 23.9pt;
  color: #fff;
}
.op-subtitle {
  margin-top: 2.9pt;
  font-size: 6.5pt;
  line-height: 8.7pt;
  letter-spacing: 2.1pt;
  text-transform: uppercase;
  color: var(--op-gold-pale);
}
.op-meta {
  margin-top: 4.3pt;
  font-family: var(--op-serif);
  font-style: italic;
  font-size: 7.5pt;
  line-height: 8.5pt;
  color: var(--op-mist);
}

/* ── body ─────────────────────────────────────────────────────────────── */
.op-body { padding: 0 38pt; }

.bbl-onepager .op-label {
  font-size: 5.5pt;
  line-height: 7.3pt;
  font-weight: 700;
  letter-spacing: 1.7pt;
  text-transform: uppercase;
  color: var(--op-gold);
}
.op-label-first { padding-top: 9pt; }

.bbl-onepager .op-headline {
  margin-top: 3.3pt;
  font-family: var(--op-serif);
  font-weight: 700;
  font-size: 15pt;
  line-height: 17pt;
  color: var(--op-navy);
}
.bbl-onepager .op-lede { margin-top: 6.5pt; }
.bbl-onepager .op-lede b,
.bbl-onepager .op-text b,
.bbl-onepager .op-callout b {
  font-weight: 700;
  color: var(--op-navy);
}

/* Section headings: small-caps navy on a 2pt gold rule. The gap above and
   below differs per section because it does on the page this was measured
   from — each is set so the block below lands where Frank's did. */
.bbl-onepager .op-sec {
  /* Word's paragraph border runs 1.4pt left and 1.6pt right of the text
     (36.6 -> 575.6pt); the text itself stays on the 38pt margin. */
  margin-left: -1.4pt;
  margin-right: -1.6pt;
  padding: 0 1.6pt 2pt 1.4pt;
  border-bottom: 2pt solid var(--op-gold);
  font-size: 6.5pt;
  line-height: 8.7pt;
  font-weight: 700;
  letter-spacing: 1.7pt;
  text-transform: uppercase;
  color: var(--op-navy);
}
.bbl-onepager .op-sec-core { margin-top: 4.5pt; margin-bottom: 4.9pt; }
.bbl-onepager .op-sec-second { margin-top: 5pt; margin-bottom: 2.8pt; }
.bbl-onepager .op-sec-steps { margin-top: 4.3pt; margin-bottom: 3pt; }
.bbl-onepager .op-sec-includes { margin-top: 5.5pt; margin-bottom: 4.6pt; }
.bbl-onepager .op-sec-timeline { margin-top: 3.4pt; margin-bottom: 4pt; }

/* the feature list — two columns, gold diamonds */
.op-bullets {
  display: grid;
  grid-template-columns: 280.1pt 1fr;
}
.bbl-onepager .op-bullets li {
  position: relative;
  padding-left: 6.2pt;
  margin-bottom: 3pt;
}
.bbl-onepager .op-bullets li::before,
.bbl-onepager .op-includes li::before {
  content: "\25C6";
  position: absolute;
  left: 0;
  top: 1.5pt;   /* on the x-height, where Word's diamond sits — not up at cap height */
  font-family: "Segoe UI Symbol", "Cambria Math", var(--op-sans);
  font-size: 4.5pt;
  font-weight: 400;
  color: var(--op-gold);
}

.op-callout {
  margin: 3.7pt 0 0 -1.6pt;
  padding: 5.6pt 12pt 5.6pt 8.6pt;
  background: var(--op-card);
  border-left: 3pt solid var(--op-gold);
  line-height: 12.8pt;
  color: var(--op-navy);
}

.bbl-onepager .op-text {
  line-height: 12.6pt;
  margin-bottom: 3.8pt;
}

/* the three example questions */
.op-quotes,
.op-steps {
  display: grid;
  grid-template-columns: repeat(3, 172.6pt);
  column-gap: 9.1pt;
}
.op-quote {
  display: flex;
  align-items: center;
  justify-content: center;
  /* 25pt tall with the text 8.6pt under the rule's top, as Word lays it out
     (its cell line box is taller than the 7.5pt italic it holds). */
  padding: 6.8pt 6pt 7.6pt;
  background: var(--op-card);
  border-top: 2pt solid var(--op-gold);
  font-family: var(--op-serif);
  font-style: italic;
  font-size: 7.5pt;
  line-height: 8.6pt;
  color: var(--op-navy);
  text-align: center;
}

/* the three steps */
.op-step {
  padding: 5pt 7.8pt 5.4pt;
  background: var(--op-card);
  border: 0.375pt solid var(--op-rule);
  border-top: 2pt solid var(--op-gold);
}
.op-step-n {
  font-family: var(--op-serif);
  font-weight: 700;
  font-size: 12.5pt;
  line-height: 14.2pt;
  color: var(--op-gold);
}
.op-step-title {
  margin: 0.8pt 0 4.4pt;
  font-size: 6pt;
  line-height: 8pt;
  font-weight: 700;
  letter-spacing: 1pt;
  text-transform: uppercase;
  color: var(--op-navy);
}
.op-step-text {
  font-size: 8pt;
  line-height: 11.6pt;
  color: var(--op-slate);
}

/* what is included — three columns that start on the cards' own edges */
.bbl-onepager .op-includes {
  display: grid;
  grid-template-columns: 181.7pt 181.7pt 1fr;
}
.bbl-onepager .op-includes li {
  position: relative;
  padding: 0 8pt 0 10pt;
  margin-bottom: 3.2pt;
  font-size: 8pt;
  line-height: 11pt;
  color: var(--op-slate);
}
.bbl-onepager .op-includes li b {
  font-weight: 700;
  color: var(--op-navy);
}

/* the timeline — a grid, not a <table> (see OnePagerSheet.jsx: Atelier's
   `main table td` idiom is !important and would restyle the preview copy) */
.op-tl-row {
  display: grid;
  grid-template-columns: 189.1pt 1fr;
  border-bottom: 0.375pt solid var(--op-rule);
}
.op-tl-row > div {
  padding: 2.4pt 7pt 2.6pt;
  font-size: 8.5pt;
  line-height: 11.4pt;
}
.op-tl-head > div {
  padding: 1.8pt 7pt 3.4pt;
  font-size: 6pt;
  line-height: 8pt;
  font-weight: 700;
  letter-spacing: 1.2pt;
  text-transform: uppercase;
  color: var(--op-navy);
}
.op-tl-row > .op-when {
  font-weight: 700;
  text-transform: uppercase;
  color: var(--op-navy);
}
.op-tl-row > .op-what { color: var(--op-slate); }

/* ── the result and the price: a full-bleed navy band ──────────────────── */
.op-band {
  display: grid;
  grid-template-columns: 330.1pt 1fr;
  margin-top: 4.8pt;
  background: var(--op-navy);
}
.op-result {
  align-self: center;
  padding: 13.7pt 20pt 12.3pt 54pt;
}
.op-invest { padding: 14.1pt 38pt 13pt 22pt; }
.op-close {
  margin-top: 5.2pt;
  font-family: var(--op-serif);
  font-size: 10.5pt;
  line-height: 13.2pt;
  color: #fff;
  white-space: pre-line;   /* the two lines of the result, as typed */
}
.op-price {
  font-size: 8.5pt;
  line-height: 17.4pt;
  color: #fff;
}
.op-invest .op-label + .op-price { margin-top: 1.9pt; }
.op-fig {
  font-family: var(--op-serif);
  font-weight: 700;
  font-size: 12.5pt;
  /* The 12.5pt figure must not stretch its 8.5pt line: with the inherited
     line-height it did, and the two price lines sat 18.5pt apart, not 17.4. */
  line-height: 0;
  color: var(--op-gold-pale);
}
.op-note {
  margin-top: -0.6pt;
  font-size: 7pt;
  line-height: 10.4pt;
  color: var(--op-mist);
}

/* ── footer, at the foot of the page ───────────────────────────────────── */
.op-foot {
  position: absolute;
  /* the rule spans 36.6 -> 575.6pt like Word's; the text keeps the margins */
  left: 36.6pt;
  right: 36.4pt;
  bottom: 8.5pt;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: baseline;
  padding: 1.8pt 1.6pt 0 1.4pt;
  border-top: 2pt solid var(--op-gold);
  font-size: 8pt;
  line-height: 9.1pt;
  color: var(--op-navy);
}
.op-foot-name { font-family: var(--op-serif); font-weight: 700; }
.op-foot-note { font-family: var(--op-serif); font-style: italic; text-align: center; }
.op-foot-site {
  justify-self: end;
  font-family: var(--op-sans);
  font-weight: 700;
  font-size: 6.5pt;
  color: var(--op-gold);
}

/* ── drawn at 3x, then scaled back down ─────────────────────────────────────
 * Chrome snaps every border AND box to whole CSS pixels — at 96dpi a 2pt rule
 * (2.67px) prints 1.5pt and a line of text can only sit on a 0.75pt grid.
 * Measured 2026-09-10: at normal scale the page's gold rules were 1.5pt against
 * the Word template's 2pt, and the drift they caused put the lower half 7pt
 * higher. Laid out with `zoom: 3` and scaled back by 1/3, the same rules print
 * at exactly 2.000pt and positions land on a 0.25pt grid — which is what lets
 * this page be identical to the Word template rather than merely close to it.
 * The layout inside is unchanged; only the resolution it is drawn at. */
.op-hires { zoom: 3; }

/* ── the live preview on the tab ───────────────────────────────────────── */
.op-preview-frame {
  position: relative;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 1px 2px rgba(22, 38, 74, 0.12), 0 8px 24px rgba(22, 38, 74, 0.10);
}
.op-preview-scale { transform-origin: top left; }
/* Where page one ends, drawn only when the content runs past it. */
.op-page-end {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 2px dashed #b3261e;
  pointer-events: none;
}
.op-page-end span {
  position: absolute;
  right: 8px;
  top: 4px;
  font: 700 11px/1 "Segoe UI", system-ui, sans-serif;
  color: #b3261e;
  background: #fff;
  padding: 2px 6px;
}

/* ── printing ──────────────────────────────────────────────────────────────
 * The print copy is portalled straight into <body>, OUTSIDE the app, and the
 * rules below only fire while the One-pager tab has put `bbl-print-onepager`
 * on <body> — so printing any other page of the Command Center is untouched.
 * Hiding the app with display:none (not visibility) is safe here because the
 * sheet is not inside it: nothing collapses around the page that prints, and a
 * tall app shell cannot paginate blank pages after it. The zero page margin
 * (the navy runs to the paper's edge) is a <style> the tab adds on mount and
 * removes on unmount, for the same reason: @page cannot be scoped by selector.
 * ─────────────────────────────────────────────────────────────────────────── */
.bbl-onepager-print { display: none; }

/* The print copy at 3x: a Letter-sized box that clips, holding the zoomed page
   scaled back to size. One page by construction — which is only right when the
   content fits, so the tab falls back to the plain (paginating) copy when it
   does not, and an over-long proposal still prints on two pages. */
.op-print-clip {
  position: relative;
  width: 8.5in;
  height: 11in;
  overflow: hidden;
}
.op-print-clip > .op-hires {
  position: absolute;
  top: 0;
  left: 0;
  transform: scale(0.3333333);
  transform-origin: 0 0;
}

@media print {
  html:has(body.bbl-print-onepager),
  body.bbl-print-onepager {
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
    margin: 0 !important;
    padding: 0 !important;
    background: #fff !important;
  }
  body.bbl-print-onepager > *:not(.bbl-onepager-print) { display: none !important; }
  body.bbl-print-onepager > .bbl-onepager-print { display: block !important; }
}
/* BBL Command Center — interaction layer.
 *
 * DESIGN SAMPLE 3 — "The Study" (executive briefing-room dark theme).
 * Hover/motion retuned to the dark charcoal + brass palette; structure and
 * class names unchanged.
 *
 * Scoped TIGHTLY to what inline styles cannot express: :hover states,
 * transitions, and @keyframes. Imported once from src/main.jsx.
 */

/* --------------------------------------------------------------------------
 * Keyframes — live status dots
 * ------------------------------------------------------------------------ */
@keyframes bbl-pulse-dot {
  0%, 100% { box-shadow: 0 0 0 3px rgba(95, 158, 125, 0.22); }
  50%      { box-shadow: 0 0 0 5px rgba(95, 158, 125, 0.1); }
}

.bbl-live-dot {
  animation: bbl-pulse-dot 2s ease-in-out infinite;
}
.bbl-live-pulse {
  animation: bbl-pulse-dot 1.8s ease-in-out infinite;
}

/* --------------------------------------------------------------------------
 * Masthead nav links + roster medallions
 * ------------------------------------------------------------------------ */
.bbl-masthead-link {
  transition: color 0.15s, border-color 0.15s;
}
.bbl-masthead-link:hover {
  color: var(--bbl-accent-hi);
}

.bbl-medallion {
  transition: transform 0.18s, filter 0.18s;
}
.bbl-medallion:hover {
  transform: translateY(-3px);
  filter: drop-shadow(0 6px 14px rgba(var(--bbl-accent-tint-rgb), 0.25));
}
.bbl-medallion:hover span:first-of-type {
  color: var(--bbl-accent-hi);
}

/* --------------------------------------------------------------------------
 * Top bar buttons + partner pill
 * ------------------------------------------------------------------------ */
.bbl-top-btn,
.bbl-partner-pill {
  transition: background 0.15s, border-color 0.15s;
}
.bbl-top-btn:hover,
.bbl-partner-pill:hover {
  border-color: var(--bbl-accent-line);
  background: rgba(var(--bbl-accent-tint-rgb), 0.14);
}

/* Sticky agent ribbon removed 2026-07-23 (it leaked across page
   navigations). Its classes (.bbl-sticky-ribbon / .bbl-ribbon-*) are
   intentionally gone; the roster grid is the sole agent-nav surface. */

/* --------------------------------------------------------------------------
 * Agents grid — tile hover lift + brass top-border scaleX reveal
 * ------------------------------------------------------------------------ */
.bbl-agent-tile {
  transition: border-color 0.18s, transform 0.18s, box-shadow 0.18s, color 0.18s;
}
.bbl-agent-tile::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--bbl-accent-line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.18s;
}
.bbl-agent-item:hover .bbl-agent-tile {
  border-color: var(--bbl-accent-line-2);
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
  color: var(--bbl-accent-hi);
}
.bbl-agent-item:hover .bbl-agent-tile::before {
  transform: scaleX(1);
}

/* --------------------------------------------------------------------------
 * Quick Actions — primary + secondary button hovers
 * ------------------------------------------------------------------------ */
.bbl-qa-primary {
  transition: background 0.15s, border-color 0.15s;
}
.bbl-qa-primary:hover {
  background: #33466a;
  border-color: var(--bbl-accent-line);
}
.bbl-qa-btn {
  transition: background 0.15s, border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.bbl-qa-btn:hover {
  background: #33466a;
  border-color: var(--bbl-accent-line);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
}
.bbl-qa-arrow {
  transition: transform 0.15s, color 0.15s;
}
.bbl-qa-btn:hover .bbl-qa-arrow {
  color: var(--bbl-accent-hi);
  transform: translateX(2px);
}

/* --------------------------------------------------------------------------
 * Handoff Notes — add-note pill
 * ------------------------------------------------------------------------ */
.bbl-handoff-add {
  transition: background 0.15s, transform 0.15s, box-shadow 0.15s;
}
.bbl-handoff-add:hover {
  background: #33466a;
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);
}

/* --------------------------------------------------------------------------
 * Sign-offs — approve / reject buttons
 * ------------------------------------------------------------------------ */
.bbl-signoff-btn {
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.bbl-signoff-btn-approve:hover { background: #4c8467; }
.bbl-signoff-btn-reject:hover  { border-color: #b0413e; color: #cd6a63; }

/* --------------------------------------------------------------------------
 * Needs Attention — item row hover
 * ------------------------------------------------------------------------ */
.bbl-attn-item {
  transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.bbl-attn-item:hover {
  transform: translateX(2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  border-color: var(--bbl-accent-line-2);
}

/* --------------------------------------------------------------------------
 * Live Activity — event row hover
 * ------------------------------------------------------------------------ */
.bbl-activity-row {
  transition: background 0.12s;
}
.bbl-activity-row:hover {
  background: rgba(var(--bbl-accent-tint-rgb), 0.06);
}

/* Messages panel search — placeholder + clear button on the dark title bar. */
[data-testid="messages-search"]::placeholder {
  color: rgba(255, 255, 255, 0.5);
}
[data-testid="messages-search"]::-webkit-search-cancel-button {
  filter: invert(1);
  opacity: 0.5;
  cursor: pointer;
}

/* --------------------------------------------------------------------------
 * Week Calendar — day cell hover (today cell keeps its slate fill)
 * ------------------------------------------------------------------------ */
.bbl-week-day {
  transition: border-color 0.15s, background 0.15s;
}
.bbl-week-day:hover {
  border-color: var(--bbl-accent-line);
}
/* Today's cell is a soft gold wash set inline per cell (2026-07-23), no longer
   a navy fill; this only carries its gold hover border. */
.bbl-week-day.is-today:hover {
  border-color: var(--bbl-gold, var(--bbl-accent-line));
}

/* --------------------------------------------------------------------------
 * Generic agent-tile / cost-row / signoff-item — subtle shared hovers
 * ------------------------------------------------------------------------ */
.bbl-hoverable {
  transition: background 0.15s, border-color 0.15s;
}

/* --------------------------------------------------------------------------
 * Masthead BB monogram — the asset is a black-on-transparent PNG, invisible on
 * the dark masthead. In dark mode recolor it to white (brightness(0) forces the
 * silhouette solid black preserving alpha, invert(1) flips black -> white).
 * Light mode leaves the original black lockup on the cream masthead untouched.
 * ------------------------------------------------------------------------ */
:root[data-theme="dark"] [data-testid="header-home-logo"] img {
  filter: brightness(0) invert(1);
}

/* --------------------------------------------------------------------------
 * Header focus rings — dark surfaces take a brass ring
 * ------------------------------------------------------------------------ */
[data-testid="header-home-logo"]:focus-visible,
[data-testid="header-home-title"]:focus-visible,
[data-testid="feedback-button"]:focus-visible,
[data-testid="header-notif-btn"]:focus-visible,
[data-testid="mobile-nav-toggle"]:focus-visible,
[data-testid="partner-switcher"]:focus-visible {
  outline: 2px solid var(--bbl-gold-bold, var(--bbl-accent-line));
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
 * Stat band — clickable figure cells (tickets → Feedback, tasks → Tasks,
 * spend → Costs). Subtle tint + focus ring; the repo cell is static.
 * ------------------------------------------------------------------------ */
.bbl-stat-cell {
  transition: background 0.15s;
}
.bbl-stat-cell:hover {
  background: rgba(var(--bbl-gold-rgb), 0.07);
}
.bbl-stat-cell:focus-visible {
  outline: 2px solid var(--bbl-gold-bold, var(--bbl-accent-line));
  outline-offset: -2px;
}

/* --------------------------------------------------------------------------
 * Mobile masthead / drawer BB mark — same black-on-transparent PNG as the
 * desktop lockup, so recolor it to white in dark mode.
 * ------------------------------------------------------------------------ */
:root[data-theme="dark"] .bbl-mobile-mark {
  filter: brightness(0) invert(1);
}

/* --------------------------------------------------------------------------
 * Mobile nav drawer — scrim fade + panel slide-in
 * ------------------------------------------------------------------------ */
@keyframes bbl-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes bbl-drawer-in {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  [data-testid="mobile-nav-drawer"],
  [data-testid="mobile-nav-scrim"] {
    animation: none !important;
  }
}

/* --------------------------------------------------------------------------
 * Skip-link + surface focus rings
 * ------------------------------------------------------------------------ */
.bbl-skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  padding: 8px 16px;
  background: var(--bbl-navy, #2a3a58);
  color: #ece7dc;
  border-radius: 4px;
  z-index: 10000;
  text-decoration: none;
  font-family: var(--bbl-font-sans, system-ui);
  font-size: 13px;
}
.bbl-skip-link:focus,
.bbl-skip-link:focus-visible {
  top: 8px;
  outline: 2px solid var(--bbl-gold-bold, var(--bbl-accent-line));
  outline-offset: 2px;
}

[data-testid^="goal-row-"]:focus-visible,
[data-testid^="feedback-row-"]:focus-visible,
[data-testid^="feedback-bucket-header-"]:focus-visible,
[role="menuitem"]:focus-visible {
  outline: 2px solid var(--bbl-gold-bold, var(--bbl-accent-line));
  outline-offset: 2px;
}

/* A row that scrolls sideways inside itself (sticky tab strips) must not draw a
   scrollbar — the row is short and the bar would sit on top of the tabs. Touch
   scrolling and keyboard scrolling both still work; only the chrome is hidden.
   Firefox uses scrollbar-width, set inline alongside this rule. */
.bbl-no-scrollbar::-webkit-scrollbar {
  display: none;
}

/* Arrival highlight (Jackson 2026-08-15) — HighlightTarget stamps this on the
   row a notification pointed at, then removes it after ~2.2s. It exists because
   landing on the right PAGE was not the same as landing on the right THING: you
   still had to scan a dashboard for the sign-off you had just been told about.
   Uses the same gold as the rest of the shell, and animates opacity/box-shadow
   only so it never reflows the row it is drawing attention to. */
@keyframes bbl-highlight-flash {
  0%   { box-shadow: 0 0 0 2px var(--bbl-gold); }
  70%  { box-shadow: 0 0 0 2px var(--bbl-gold); }
  100% { box-shadow: 0 0 0 2px transparent; }
}
[data-bbl-highlight] {
  animation: bbl-highlight-flash 2.2s ease-out forwards;
  border-radius: 6px;
  scroll-margin-top: 96px;
  scroll-margin-bottom: 96px;
}
@media (prefers-reduced-motion: reduce) {
  [data-bbl-highlight] { animation: none; box-shadow: 0 0 0 2px var(--bbl-gold); }
}

/* ── SCROLL AFFORDANCE FOR HORIZONTAL STRIPS (2026-09-07) ─────────────────
   .bbl-no-scrollbar hides the scrollbar on the app's horizontal strips — the
   phone tab chips, the Messages conversation rail, the CFO's action row. That
   is the right call visually (a bar sitting on top of a 32px row of chips is
   worse than no bar) but it removed the ONLY signal that the row scrolls at
   all. On a 390px phone the strips then read as broken rather than scrollable:
   the Clients chips ended on a hard-clipped "CONSULTS|", the CFO's tabs on
   "REVIE|", its action row on "Ask a que…".

   A right-edge fade says "there is more" without adding chrome. It is painted
   with a mask so it works over ANY background (these strips sit on three
   different grounds) and needs no extra element in the markup.

   `mask-image` only — no `background: linear-gradient` — so the fade never
   paints over the content when the browser does not support masks: the
   fallback is simply today's behaviour, which is a hard edge, not a smear. */
.bbl-scroll-fade {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
}

/* The fade is a lie once you have reached the end of the strip, so it is
   removed when the row is fully scrolled. The class is toggled by the
   scroll handler that owns the strip; where no handler exists the static fade
   is still the better default, because a strip that cannot scroll is also a
   strip whose last chip is not clipped. */
.bbl-scroll-fade[data-at-end="1"] {
  -webkit-mask-image: none;
  mask-image: none;
}

/* Reduced motion does not disable this — it is not motion, it is a static
   gradient. But a high-contrast preference should not have content fading out,
   so the fade is dropped there in favour of the honest hard edge. */
@media (prefers-contrast: more) {
  .bbl-scroll-fade { -webkit-mask-image: none; mask-image: none; }
}

/* ── A finger-sized tap area for small controls (2026-09-10 phone pass) ─────
   The phone audit measured controls a thumb cannot reliably hit: the message
   like-heart at 17×17px, the notices ✕ at 20×20, "See all" at 33×15, "← All
   clients" at 94×14, the Tasks "Expand all" / "Clear filters" links at 14px
   tall. Making them BIGGER would reflow the rows they sit in, so instead an
   invisible box extends each one's hit area by 10px on every side. Pseudo-
   elements are part of their element for hit-testing, so a tap in that halo
   IS a tap on the control; nothing about how it looks changes.
   Phone only: with a mouse the halo would just steal clicks from neighbours. */
@media (max-width: 700px) {
  .bbl-hit { position: relative; }
  .bbl-hit::after {
    content: '';
    position: absolute;
    inset: -10px;
  }
}

/* ── No zoom on tap (2026-09-10, phone UI/UX pass) ─────────────────────────
   iOS zooms the whole page into any text field whose font is under 16px the
   moment it is focused — and in the installed app there is no pinch-out
   habit to undo it, so the page simply stays zoomed and the next screen opens
   magnified. The audit of every Command Center page at 390px found 60+ fields
   at 10.5–13.5px: the Tasks filters and search, every client stage dropdown,
   the dashboard scratchpad, the Helpdesk filters, the Workshop inputs.

   16px on a phone is the fix, not `maximum-scale=1` in the viewport meta —
   that would also take pinch-zoom away from anyone who needs it on Android.

   `!important` because nearly every field here sets its size INLINE, and an
   inline style beats any normal stylesheet rule. It is scoped to the phone
   width, where the zoom happens, and to the field types that take typing:
   checkboxes, radios, sliders, colour and file pickers are not affected. The
   agent pages render in this same document, so this reaches them too.

   The `#bbl-no-zoom` inside :is() never matches anything — it is there for
   its SPECIFICITY. :is() takes the specificity of its most specific argument,
   so this rule carries an ID's weight and outranks the Atelier skin's own
   `!important` sizes (e.g. the Tasks selects at `:root[data-ui="atelier"]
   [data-testid="tasks-sort"] { font-size: 12px !important }`). Without it a
   plain `select` lost to those, and the phone-pass spec caught a 12px field
   still on the page. */
@media (max-width: 700px) {
  :is(
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="hidden"]),
    select,
    textarea,
    #bbl-no-zoom
  ) {
    font-size: 16px !important;
  }
}
/*$vite$:1*/