:root{--ink:#16140F;--ink2:#14120E;--ink3:#0F0E0B;--bronze:#6B4F1C;--gold:#C7A24B;--gold2:#B0863C;--goldHover:#D4B45F;--cream:#FBF6EC;--cream2:#F1E9DB;--cream3:#EBE0CC;--ink2b:#221D15;--cream4:#F4EBD9;--body:#4A4435;--body2:#2C2820;--muted:#6A6353;--gold-text:#7A5A20;--advance-on-dark:#509575;--expose-on-dark:#E0857A;--muted-on-dark:rgba(241,233,219,.72);--up:#386F45;--down:#B23A2E;--advance:#1D7148;--advanceBright:#167247;--expose:#A6402E;--red:#A6402E;--green:#1D7148;--rad:6px;--radDoc:0;--adv:var(--advance);--advb:var(--advanceBright);--exp:var(--expose);--paper:var(--cream2);--paper2:var(--cream);--card:var(--cream);--canvas:var(--cream3);--umber:var(--bronze);--bronze-fill:var(--bronze);--stone:var(--body);--stone2:var(--body2);--obsid:var(--ink2);--obsid2:var(--ink3)}:root{--serif:'Newsreader',Georgia,'Times New Roman',serif;--sans:'Manrope',system-ui,-apple-system,'Segoe UI',sans-serif;--mono:'Spline Sans Mono',ui-monospace,SFMono-Regular,Menlo,monospace;--line:rgba(22,20,15,.16);--lineD:rgba(241,233,219,.16);--rad:6px;--wrap:1180px}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--cream);color:var(--ink);font-family:var(--sans);font-size:14px;line-height:1.55}
/* v4: the display face reads as a serif at its natural weight, never as a bold sans substitute.
   Tracking is always negative on display type, and a statement heading drops to 300. */
h1,h2,h3,h4{font-family:var(--serif);font-weight:400;letter-spacing:-.02em;margin:0;text-wrap:balance}
h1{letter-spacing:-.03em}
.statement{font-weight:300}
a{color:inherit}
img,svg{max-width:100%}
table{border-collapse:collapse;width:100%}
/* Wide content scrolls inside its own container so the page never scrolls sideways. */
.scroll-x{overflow-x:auto;-webkit-overflow-scrolling:touch}
/* Visible keyboard focus. Its absence is the single most common a11y defect here. */
:focus-visible{outline:2px solid var(--gold-text);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
/*
 * THE MASTHEAD, and it is the same one on every surface.
 *
 * Gold covers dark, per v4: eyebrows, the active tab and the mark's diagonal. Bronze never appears
 * on ink. The nav sits on the left beside the wordmark rather than the right, because it is the
 * primary thing on this bar and the right edge is where the account controls live.
 *
 * Minimum hit target is 44px on anything tappable, which is why the links carry vertical padding
 * that looks generous against 12px type.
 */
/*
 * THE SHARED CHROME DEFINES THE TOKENS IT USES, LOCALLY.
 *
 * A page is free to retune a token for its own ground, and an ink page has to: the shared --muted
 * is darkened to clear AA on cream and fails from the other direction on ink. Social Studio does
 * exactly that at the :root level, which is the only place a page can do it, and :root is above the
 * masthead in the cascade. So the ink page's cream-coloured --muted reached the surface bar, whose
 * ground is cream, and the Instagram pill rendered as cream text on cream: present, styled, and
 * invisible.
 *
 * Redeclaring here makes the chrome independent of what any page does above it. This is the same
 * defect as the bare header selector in a different costume: shared markup is not shared until it
 * stops depending on the page around it.
 */

:root{
  /* grounds */
  --s-page:var(--ink);        /* #16140F */
  --s-bar:var(--ink2);        /* #14120E, the top bar */
  --s-strip:#1D1913;          /* the strip, and the gold bordered attention panel */
  --s-raise:#1A1611;          /* rails, cards, raised surfaces */
  --s-band:#221D16;           /* table header bands, current nav item, hover, inset panels */
  --s-sel:#2E2618;            /* selected: current stage, chosen route, active filter, verdict */
  /* 3px, the application radius, from 01-SHELL and 06-TOKENS. Distinct from --rad at 6px, which is
     the app chrome radius the design brief set. Both are real: the brief's 6px governs the surfaces
     built before this handoff and this governs the platform shell. Named rather than typed, because
     a bare 3 in forty places is a value nobody can change. */
  --s-rad:3px;
  /* lines */
  --s-line:#322C22;           /* standard border, table rules, grid beds */
  --s-line2:#4A4132;          /* stronger: secondary buttons, unsigned gate dots, control boxes */
  --s-hair:var(--gold-text);  /* #7A5A20, gold hairline behind stale and time sensitive marks */
  /* text, measured on #1A1611 */
  --s-head:#F3EDE0;           /* 14.9:1 headings, current nav */
  --s-num:#F0E2BC;            /* 13.0:1 numerals in Newsreader */
  --s-body:#ECE5D6;           /* 13.4:1 body */
  --s-second:#C9BFA9;         /*  9.6:1 secondary, default nav */
  --s-note:#A29781;           /*  6.2:1 notes and detail */
  --s-colhead:#9A9081;        /*  6.0:1 DIM TEXT ON THE BAND, wherever it sits. NOT --s-dim, which
                                 measures 4.46 there and fails. Found first on table column headers,
                                 twenty two nodes in the previous build, and the name still says so.
                                 It is the wrong name: the same failure was sitting on every chip in
                                 the console, because a chip is band on panel too and took --s-dim
                                 for its text. Read it as the band tone rather than as a table one. */
  --s-dim:#8C8371;            /*  4.8:1 the floor. Nothing dimmer carries text anywhere. */
  /* accents */
  --s-gold:var(--gold);       /* #C7A24B current markers, primary fill, focus ring */
  --s-goldtext:#D9C48D;       /* gold text on ink, links, waiting */
  --s-done:var(--gold2);      /* #B0863C done state numerals */
  --s-good:#7FBF99;           /* healthy, signed, accepted, kept, high confidence, live */
  --s-caution:#D9A441;        /* stale, not ratable, unclassified */
  --s-fault:#E07A6C;          /* degraded, refused, blocked, low confidence, sub threshold */
  --s-badge:#B3402E;          /* badge fill */
  --s-badgetext:#FFF1ED;      /* badge numerals */
}

.mast,.mast-bar{--muted:#6A6353;--line:rgba(22,20,15,.16);--lineD:rgba(241,233,219,.16)}
/* 52px, per 01-SHELL. Sticky so the frame never scrolls away from an analyst mid table. */
.mast{background:var(--s-bar);color:var(--s-body);border-bottom:1px solid var(--s-line);
  position:sticky;top:0;z-index:20}
.mast-row{min-height:52px}
/* 4px, which is what reconciles two specifications rather than picking one.
   01-SHELL sets the top bar at 52px and draws its pills at 9px 13px padding, which is about 32px
   tall. DESIGN-BRIEF.md sets a 44px minimum on anything tappable and does not qualify it. A 32px
   navigation target fails that, and a 44px pill in a 52px bar leaves exactly 4px either side.
   So the bar is the specified 52 and the target is the specified 44, and neither document loses. */
.mast-row{display:flex;align-items:center;gap:16px;flex-wrap:wrap;max-width:var(--wrap);
  margin:0 auto;padding:4px 22px}
.mast-brand{display:flex;align-items:center;gap:9px;text-decoration:none;color:var(--cream2);
  padding:6px 0;min-height:44px}
.mast-brand svg{width:20px;height:auto;flex:none}
.mast-brand b{font-family:var(--serif);font-weight:400;font-size:17px;letter-spacing:-.01em}
.mast-brand span{font:700 9px/1 var(--sans);letter-spacing:.11em;text-transform:uppercase;color:var(--gold)}
/*
 * EVERY TAPPABLE THING IN THE CHROME IS 44px TALL, and none of it was until 2026-08-19.
 *
 * The design brief states the rule without qualification: a minimum hit target of 44px on anything
 * tappable. This masthead shipped with nav links and Sign out at 34px, and the surface bar's pills
 * and action buttons at 32px. Only the bar's own row carried 44, which measures the STRIP rather
 * than anything a person aims at.
 *
 * It passed the whole suite because nothing asserted it. That is the same shape as the defect on
 * the marketing site the same day, where a link kept a 44px box while the rule inside it drifted
 * twenty pixels away from the words: a geometry rule nobody measures is a comment.
 *
 * THE HEIGHT IS REAL, NOT PAINTED SMALLER. Keeping a 34px pill and padding the hit area out to 44
 * is possible, with background-clip:content-box to stop the fill following the padding. It was
 * not taken. A target you cannot see the edge of is a target a person misses from the other
 * direction, and the honest version of "this is 44px" is 44 pixels of element.
 *
 * test/chromeHitTarget.test.js reads these declarations and fails on a smaller one, so the next
 * value added here is checked rather than trusted.
 */
.mast-nav{display:flex;gap:2px;flex-wrap:wrap;align-items:center}
/* The brief: "The active tab is a gold fill with ink text; inactive tabs are a hairline border
   with cream text at 72% opacity." The hairline was missing, so an inactive tab was a word rather
   than a control and the row read as a sentence with one button in it. */
.mast-nav a{display:flex;align-items:center;min-height:44px;font:500 12.5px/1 var(--sans);text-decoration:none;
  color:var(--s-second);padding:9px 13px;border:1px solid var(--s-line2);border-radius:var(--s-rad);
  white-space:nowrap}
.mast-nav a:hover{color:var(--s-head);background:var(--s-band)}
.mast-nav a.on{color:var(--s-page);background:var(--s-gold);border-color:var(--s-gold)}
.mast-spacer{flex:1}
.mast-out{display:flex;align-items:center;min-height:44px;font:700 11.5px/1 var(--sans);text-decoration:none;
  color:rgba(241,233,219,.72);border:1px solid var(--lineD);border-radius:var(--rad);padding:0 12px}
.mast-out:hover{color:var(--gold);border-color:var(--gold)}
/* Engine version, outermost right, per the brief. Metadata rather than a control, so it takes the
   mono label treatment and no hit target: it is not tappable. */
.mast-ver{font:400 11px/1 var(--mono);letter-spacing:.06em;color:var(--s-dim);
  white-space:nowrap;align-self:center}

/*
 * THE SURFACE BAR, under the masthead. Two jobs, one strip.
 *
 * A DEEP PAGE SAYS WHERE IT SITS AND OFFERS THE WAY OUT. The primary nav cannot do this. The survey
 * editor belongs under the console and a dossier belongs under Dossiers, and the nav has one entry
 * for each of those parents and no idea which child you are in. Without it, a page reached by
 * clicking a row in a table has no way back except the browser button.
 *
 * A SURFACE'S OWN CONTROLS SIT HERE TOO, and not in the masthead. Intelligence carries a lens and
 * an edition selector; putting them in the identity bar took it to 107px at 1280px wide, wrapping
 * the primary nav onto one line and Sign out onto another. The masthead holds what every surface
 * has. Anything one surface has goes below it, where a wide control costs nothing.
 */
/* THE STRIP IS INK. The live build drew it in cream and 08-CONTRADICTIONS item 7 is explicit
   that ink wins: the stacking is what the owner liked and only the ground changed. */
.mast-bar{background:var(--s-strip);color:var(--s-body);border-bottom:1px solid var(--s-line);
  position:sticky;top:52px;z-index:19}
.mast-bar .r{display:flex;align-items:center;gap:14px;flex-wrap:wrap;max-width:var(--wrap);
  margin:0 auto;padding:0 22px;min-height:44px}
/* The strip is ink now, so bronze cannot carry this: it measures 2.3 there. Gold text is the
   on-dark counterpart, per the brand rule that bronze is a light ground colour only. */
  .mast-bar .back{display:flex;align-items:center;gap:7px;min-height:44px;font:500 12px/1 var(--sans);
  color:var(--s-goldtext);text-decoration:none}
.mast-bar .back:hover{color:var(--s-head)}
.mast-bar .here{font:600 10px/1 var(--sans);letter-spacing:.11em;text-transform:uppercase;
  color:var(--s-gold)}
/* --s-dim is the text floor. A line colour is not a text colour: #4A4132 measures 1.74 here. */
.mast-bar .sep{color:var(--s-dim)}
.mast-bar .fill{flex:1}
/* Surface controls on the bar. They sit on a light ground, so bronze rather than gold. */
/* The strip's control value box, per 01-SHELL. A control on the strip is a mono uppercase label
   in --s-dim followed by this box. Sans rather than mono, because the label identifies and the
   value reads. */
.mast-bar .pill{font:500 12px/1 var(--sans);padding:7px 11px;min-height:40px;display:flex;
  align-items:center;border-radius:var(--s-rad);border:1px solid var(--s-line2);color:var(--s-body);
  background:var(--s-band)}
.mast-bar .pill.on{color:var(--s-page);background:var(--s-gold);border-color:var(--s-gold)}
/* The label beside it. */
.mast-bar .ctl{font:600 9.5px/1 var(--sans);letter-spacing:.10em;text-transform:uppercase;
  color:var(--s-dim)}
.mast-bar button.act{font:500 12px/1 var(--sans);min-height:40px;padding:7px 13px;cursor:pointer;
  border:1px solid var(--s-line2);border-radius:var(--s-rad);background:var(--s-band);color:var(--s-body)}
.mast-bar button.act:hover{border-color:var(--s-gold);color:var(--s-head)}


/*
 * THE APP SURFACE SCALE, from handoff_marga_platform/06-TOKENS.md.
 *
 * "Ink is for anything you operate. Cream is for anything you read, print or fill in, which is the
 * frozen report and the Exchange survey. Neither is in this application." So this application has
 * ONE ground and an elevation scale on top of it, and the light ground classes below exist for the
 * document surfaces that are not part of it.
 *
 * DEFINED HERE RATHER THAN IN brand.js, deliberately. brand.js is the brand palette: it is shared
 * with the marketing site and the printed report, and test/brand.test.js pins it. This is an
 * application surface scale, nineteen of its twenty four values are new to the estate, and putting
 * them in the brand file would make the marketing site inherit an app decision.
 *
 * Five values are already brand tokens and are referenced rather than restated, so a brand change
 * still reaches them: page, top bar, gold, gold 2 and the gold hairline.
 *
 * ONE NEAR COLLISION WORTH KNOWING ABOUT. The handoff's header band is #221D16 and the brand's
 * --ink2b is #221D15. One digit, almost certainly the same intended colour. The handoff value is
 * used because it is the specification and it says to recreate it exactly, and this note exists so
 * the next person does not spend an afternoon deciding which is the typo.
 */
/* The surface scale is defined once, in SURFACE_SCALE_CSS above, and reaches this stylesheet
   through CHROME_CSS. It was restated here and the two copies were an invitation. */

/*
 * GROUNDS. What a surface sits on, as tokens rather than as an ancestor class.
 *
 * Owner decision 2026-08-19: every app surface takes an ink ground with lighter accent boxes, on
 * the model of slide 13 of the guidelines. That amends DESIGN-BRIEF.md section 3, which reserved
 * ink for Sign in and Social Studio.
 *
 * WHY THIS IS NOT A .on-dark CLASS ON THE BODY. The components below already carry .on-dark
 * variants and putting that class on every page is the cheap move. It breaks on the first accent
 * box: a light panel on an ink page holds fields, tables and rules that must return to their
 * light values, and an ancestor class cannot be undone by a descendant. Every nesting would need
 * a counter-override, which is the defect class this file spent the day removing.
 *
 * So a ground declares what it provides and components consume it. A light box inside a dark page
 * sets .g-light and everything inside it flips, at any depth, with no rule naming the combination.
 *
 * BRONZE AND GOLD ARE THE SAME DECISION MADE TWICE, which is why --g-accent exists. Bronze is a
 * light ground colour only and measures 2.42 on ink; gold does that job on dark and fails on cream.
 * A component asking for --g-accent gets the right one without knowing where it is.
 */
.g-dark{
  --g-bg:var(--ink2); --g-text:var(--cream2); --g-dim:var(--muted-on-dark);
  --g-line:var(--lineD); --g-accent:var(--gold); --g-field:rgba(241,233,219,.06);
  --g-solid:var(--gold); --g-solid-text:var(--ink); --g-head:var(--ink2b); --g-row:rgba(241,233,219,.1);
  background:var(--g-bg); color:var(--g-text);
}
/* The second adjacent dark, for a dark box on a dark ground. Two identical grounds never touch. */
.g-dark2{
  --g-bg:var(--ink2b); --g-text:var(--cream2); --g-dim:var(--muted-on-dark);
  --g-line:var(--lineD); --g-accent:var(--gold); --g-field:rgba(241,233,219,.06);
  --g-solid:var(--gold); --g-solid-text:var(--ink); --g-head:var(--ink3); --g-row:rgba(241,233,219,.1);
  background:var(--g-bg); color:var(--g-text);
}
/*
 * EVERY APP SURFACE TAKES THE DARK GROUND, from the owner decision of 2026-08-19.
 *
 * Set here rather than page by page, so "all the pages have the same design" is one declaration
 * that cannot drift. A page that needs its own ground says so by putting a ground class on a
 * container; it does not restate the body.
 *
 * BASE_CSS is app only. It is served at /static/app.css and nothing else includes it: the document
 * renderers in docShell.js and reportExport.js build their own head, so a client deliverable is
 * unaffected by this and stays on paper white.
 */
body{--g-bg:var(--s-page); --g-text:var(--s-body); --g-dim:var(--muted-on-dark);
  --g-line:var(--lineD); --g-accent:var(--gold); --g-field:rgba(241,233,219,.06);
  --g-solid:var(--gold); --g-solid-text:var(--ink); --g-head:var(--ink2b); --g-row:rgba(241,233,219,.1);
  background:var(--g-bg); color:var(--g-text)}

.g-light{
  --g-bg:var(--card); --g-text:var(--ink); --g-dim:var(--muted);
  --g-line:var(--line); --g-accent:var(--bronze); --g-field:var(--cream);
  --g-solid:var(--ink); --g-solid-text:var(--paper); --g-head:var(--cream4); --g-row:rgba(22,20,15,.1);
  background:var(--g-bg); color:var(--g-text);
}
/* The alternate light band, sand. Used where two light boxes would otherwise touch. */
.g-light2{
  --g-bg:var(--cream3); --g-text:var(--ink); --g-dim:var(--muted);
  --g-line:var(--line); --g-accent:var(--bronze); --g-field:var(--cream);
  --g-solid:var(--ink); --g-solid-text:var(--paper); --g-head:var(--cream4); --g-row:rgba(22,20,15,.1);
  background:var(--g-bg); color:var(--g-text);
}

/*
 * The defaults, for anything not inside a declared ground. Light, because that is what a component
 * rendered on its own should assume, and because every document surface is light.
 */
:root{
  --g-bg:var(--card); --g-text:var(--ink); --g-dim:var(--muted);
  --g-line:var(--line); --g-accent:var(--bronze); --g-field:var(--cream);
  --g-solid:var(--ink); --g-solid-text:var(--paper);
  --g-head:var(--cream4); --g-row:rgba(22,20,15,.1);
}

/* The eyebrow, which is the same mark on every surface and took its colour from the page until
   now. Mono 600 at 10px with .2em, per the guidelines' 10 to 11px and .16 to .24em. */
.eyebrow{font:700 10px/1 var(--sans);letter-spacing:.11em;text-transform:uppercase;color:var(--g-accent)}

/*
 * FORM CONTROLS. The first shared component, 2026-08-19.
 *
 * There were none. Eight surfaces styled their own inputs and between them used FIVE different
 * light grounds for the same control, including #fff, which is not in the palette at all. Seven
 * different paddings. Two border weights, .16 and .2, for the same hairline. Only two declared a
 * height at all. That is the condition that let one surface paint a control black on black without
 * any other surface being affected or giving it away.
 *
 * ELEMENT SELECTORS, WHICH THIS ESTATE HAS BEEN BURNED BY TWICE. A bare header and a bare nav
 * in page stylesheets both landed on the shared masthead. The reason it is safe here and was not
 * there: the chrome contains no input, select or textarea of its own, so there is nothing of the
 * masthead's for these to hit. It was checked rather than assumed.
 *
 * A BASELINE RATHER THAN A TAKEOVER. Every page's inline <style> is emitted after the link to this
 * file, so at equal specificity the page still wins. Nothing already styled changes appearance;
 * what changes is that a control NOBODY styled is now correct instead of being a browser default,
 * and every new one starts on brand at 44px. Surfaces are then migrated off their copies one at a
 * time, which is a change that can be looked at rather than a flag day.
 *
 * THE EXCLUSION LIST IS A LIST OF TYPES TO SKIP, NOT A TEST FOR AN ABSENT ATTRIBUTE. The first
 * version opened with :not([type], ...), which reads as "has no type attribute AND is not a
 * checkbox AND ...". Every real input declares its type, so the rule matched almost nothing and
 * every text field on admin.html rendered at the browser default of 21px. Source review passed
 * it; the browser did not.
 *
 * :where() IS LOAD BEARING. The type list excludes checkboxes, radios, ranges and file pickers,
 * which must not become 44px cream boxes. Written as :not() the attribute selectors would raise
 * specificity to 0,1,0 and this rule would start beating the page rules it is meant to sit under.
 * :where() contributes nothing, so the whole selector stays at 0,0,1, an element selector.
 */
input:where(:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=submit],[type=button],[type=image],[type=reset])),select,textarea{
  font:400 14px/1.45 var(--sans);color:var(--g-text);background:var(--g-field);
  border:1px solid var(--g-line);border-radius:var(--rad);padding:10px 12px;min-height:44px}
textarea{min-height:88px;padding:12px;line-height:1.5;resize:vertical}
input::placeholder,textarea::placeholder{color:var(--g-dim)}
input:focus-visible,select:focus-visible,textarea:focus-visible{
  border-color:var(--g-accent);outline:2px solid var(--g-accent);outline-offset:1px}


/*
 * BUTTONS. The second shared component, 2026-08-19.
 *
 * Unlike the form control this is not pure duplication: a button genuinely has variants, and the
 * surfaces had converged on names for them without anyone deciding to. button.act is the solid one
 * on admin.html and survey-editor.html and button.mini is the quiet one, and .mini is BYTE FOR BYTE
 * IDENTICAL on both. So the shared versions take the names the codebase already agreed on, and
 * migrating a surface is deleting its copy rather than rewriting its markup.
 *
 * TWO OF NINETY THREE BUTTON RULES DECLARED A HEIGHT. Everything else was whatever padding and font
 * size happened to add up to, which is around 25px for .mini and 34px for .act against a brief that
 * asks for 44. The floor goes on the bare element so that a button nobody thought about is right,
 * which is the same argument as the control above.
 *
 * THE FLOOR IS SCOPED TO BUTTONS THAT ARE SHAPED LIKE BUTTONS. Several surfaces use a <button> as a
 * word inside a sentence, reset to no background, no border and no padding: .fbtn, button.link and
 * .draft button. Giving those a 44px box would push text around mid-paragraph. The named variants
 * take the floor and the resets do not, and :where() keeps the whole thing at element specificity
 * so a page still wins a tie.
 */
button{font-family:var(--sans);cursor:pointer}
button:where(.act,.mini,.primary,.go,.addbtn,.btn){min-height:44px;border-radius:var(--rad)}

/* The solid one. Ink ground, cream on it. */
button.act{font:700 12px/1 var(--sans);padding:0 18px;
  border:1px solid var(--g-solid);background:var(--g-solid);color:var(--g-solid-text)}
button.act:hover{filter:brightness(1.12)}

/* The quiet one, for a secondary action beside a solid. */
button.mini{font:600 11px/1 var(--sans);padding:0 12px;
  border:1px solid var(--g-line);background:transparent;color:var(--g-text)}
button.mini:hover{border-color:var(--g-accent);color:var(--g-accent)}


/*
 * CARDS AND TABLES. The third and fourth shared components, 2026-08-19.
 *
 * THE TABLE HEADER WAS THE SAME IDEA WRITTEN THREE TIMES. admin.html, console.html and
 * intelligenceRender.js each style a table head as small uppercase mono in a muted colour over a
 * hairline, and between them they use three letter spacings, three colours, three paddings and
 * three border values. Nobody chose any of that; each was written from memory of the last one.
 *
 * A BARE th AND td ARE SAFE HERE FOR THE REASON THE CONTROL ABOVE IS: the chrome has no table of
 * its own, and it already carries a bare table rule for border-collapse. Page rules come after this
 * file and win ties, so this is a baseline for the surfaces that never styled a table at all.
 *
 * --card IS AN EXISTING SEMANTIC TOKEN, var(--cream), and using it rather than a fresh value is the
 * whole point: a card ground is now one decision. Two surfaces still paint a card #fff and only one
 * of them is wrong. social.html renders previews of how a post looks on LinkedIn, in the newsletter
 * and on Instagram, and says so in a comment: those surfaces are white, and painting them from the
 * palette would make the preview stop previewing. They are deliberately left alone.
 */
/*
 * A CARD IS A RAISED DARK SURFACE, NOT A LIGHT ONE.
 *
 * 06-TOKENS puts rails, cards and raised surfaces on #1A1611 over a #16140F page. It is lighter
 * than the page, which is what "lighter accent boxes" means in an application that is ink
 * throughout: the elevation is a step up the dark scale, not a jump to cream.
 *
 * This was a light ground until 2026-08-20 and axe found the consequence rather than a review:
 * twenty failing nodes on admin and login where cream text sat on a near white field, because the
 * page's dark text tokens were inherited into a light box. Cream is for the frozen report and the
 * Exchange survey, and .g-light below still carries it for exactly those.
 */
.card{background:var(--s-raise);border:1px solid var(--s-line);border-radius:var(--s-rad);
  padding:18px}

th{text-align:left;padding:9px 12px 9px 0;font:700 9.5px/1 var(--sans);letter-spacing:.12em;
  text-transform:uppercase;color:var(--g-dim);background:var(--g-head);
  border-bottom:1px solid var(--g-line)}
td{padding:12px 12px 12px 0;border-bottom:1px solid var(--g-row);vertical-align:top}

/*
 * THE LEFT RAIL, shared geometry for the two sections that have one.
 *
 * 01-SHELL: "Two sections have one: Intelligence and Console. Same geometry, same states, different
 * contents." It lived in console.html, so Intelligence grew its own under a different class name
 * and the two drifted. Same construct, one definition.
 *
 * LINE HEIGHT IS 1.5 AND NOT 1, and the handoff calls this out as a real bug in the previous build.
 * The label span carries overflow:hidden for ellipsis, and a line height of 1 clips the descender on
 * Signals and Surveys. It is the kind of defect that reads as a font problem for a week.
 */
.rail{width:232px;background:var(--s-raise);border-right:1px solid var(--s-line);
  min-height:calc(100vh - 96px)}
.shell{display:grid;grid-template-columns:232px minmax(0,1fr);max-width:var(--wrap);margin:0 auto}
.rail-group{font:600 9.5px/1 var(--sans);letter-spacing:.10em;text-transform:uppercase;
  color:var(--s-dim);padding:20px 16px 9px}
.rail-group:first-child{padding-top:12px}
.rail a{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:40px;
  padding:9px 14px 9px 16px;font:400 13.5px/1.5 var(--sans);color:var(--s-second);
  text-decoration:none;border-left:2px solid transparent;background:transparent}
.rail a:hover{background:var(--s-band)}
.rail a.on{color:var(--s-head);border-left-color:var(--s-gold);background:var(--s-band)}
.rail a .lbl{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* The badge. A count of zero renders no badge, never a zero: an authored total drifts the moment a
   row is added, on a console whose entire subject is accurate reporting. */
.rail .badge{flex:none;min-width:22px;height:22px;border-radius:11px;padding:0 6px;
  background:var(--s-badge);color:var(--s-badgetext);font:600 12px/22px var(--mono);
  text-align:center}

/* 01-SHELL: it stays a left rail at every width. It does not flip to a top bar and it does not
   collapse to icons, so an analyst moving between a laptop and a docked monitor finds navigation in
   the same place both times. */
@media (max-width:1100px){
  .rail{width:212px}
  .shell{grid-template-columns:212px minmax(0,1fr)}
  .shell>main{padding:20px}
}

/* Section changes fade the main region. Nothing else animates. */
.shell>main{animation:mainIn 160ms ease-out}
@keyframes mainIn{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 22px}
@media print{.no-print{display:none!important}.mast{background:none;color:var(--ink)}}
@media (max-width:980px){.mast-row{padding:10px 14px;gap:12px}.wrap{padding:0 14px}.mast-bar .r{padding:6px 14px}}
