/*
 * File Portal stylesheet.
 *
 * The tokens below are the Sanctum design system's, copied as they are -
 * palette, scale, both themes - so a person moving from this portal to the
 * appliance that reads its folders meets one visual language. The component
 * rules after the tokens are the same classes Sanctum uses (.btn, .card,
 * .hero, .state, .filedrop, .datatable, .modal, .login), trimmed to what the
 * portal renders. Raw values belong in :root only.
 */


/* The typeface: Plus Jakarta Sans, bundled rather than fetched.
 *
 * An air-gapped appliance cannot reach a font service, and a page that asked
 * one would render in a fallback on every customer's screen while looking
 * right on ours. The two subsets that cover every language the documents and
 * the interface use (Latin, Latin Extended) ship in the bundle, as one
 * variable file each - every weight from 200 to 800, so the four weight
 * tokens are four real weights. Anything outside them (arrows, maths signs)
 * falls through, glyph by glyph, to Inter where it is installed and to the
 * system font otherwise. SIL Open Font License 1.1: fonts/OFL.txt. */
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-display: swap;
  font-weight: 200 800;
  src: url("./fonts/plus-jakarta-sans-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-display: swap;
  font-weight: 200 800;
  src: url("./fonts/plus-jakarta-sans-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
    U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- brand constants: identical in both themes --- */
  --brand-navy: #0b1638;
  --brand-cyan: #34b5c8;

  /* --- light theme --- */
  /* The page ground. A near-neutral rather than the blue-tinted grey this
     started as, which made every white card look like it was floating on
     water. Folded up from a second :root 1400 lines below, where it had been
     appended rather than edited - so the palette documented at the top of
     this file was not the palette that shipped. */
  --bg: #f5f6f9;
  --surface: #ffffff;
  --surface-raised: #ffffff;
  /* A well inside a surface: a search field at rest, a table's header row, a
     code block. Lower than the card it sits in, so it reads as a place to put
     something rather than as another card. */
  --surface-sunken: #f0f2f6;
  /* A row or menu item under the pointer. Quieter than the accent wash, which
     means CHOSEN - hover is only "this is what you would get". */
  --surface-hover: #f2f4f8;
  /* The person's own turn.
     A token pair, not two literals. Written as `#e8f4f8` this was a LIGHT
     bubble in BOTH themes, so on dark the near-white body text sat on a
     near-white bubble at a contrast ratio of 1.05 - the message somebody
     had just typed was invisible. */
  --bubble-user-bg: #e8f4f8;
  --bubble-user-border: #cfe7ee;
  /* The Ask screen's own blue: the send button, the greeting, the spark.
     Brighter than the navy of the chrome because the one thing this screen
     asks for is a question, and its button has to be found at a glance. */
  --ask-blue: #2563eb;
  --ask-blue-hover: #1d4fd8;
  --ask-blue-soft: #7aa2f7;
  --ask-blue-ink: #ffffff;
  --ask-glow-1: rgba(37, 99, 235, .09);
  --ask-glow-2: rgba(139, 92, 246, .07);
  /* Find's own colour. Ask writes from the model, Find writes from the
     reader's own documents: two different acts, told apart by more than a
     word, as the reference design has them. */
  --border: #e3e7ee;
  --border-strong: #cdd4e0;
  --text: #0b1638;
  --muted: #5b6579;

  --accent: #34b5c8;
  --accent-ink: #0b1638;
  /* The accent AS TEXT on a page surface - the inverse of --accent-ink,
     which is ink placed ON the accent.

     #34b5c8 measures 2.44:1 on white in Chromium, and AA wants 4.5 for text
     this small. The badge reading "Private AI Appliance" turns the accent
     colour the moment the appliance confirms it is air-gapped, so the one
     label stating the product's whole point was the least readable thing on
     the screen. Same hue, darker: 4.93:1 on --surface, 4.64:1 on --bg. */
  --accent-text: #237b88;

  --primary: #0b1638;
  --primary-ink: #ffffff;
  /* The primary under the pointer. A colour, not `filter: brightness()`: the
     filter brightened the label with the ground and blurred it on a
     low-density screen. */
  --primary-hover: #1a2a5c;

  --user-bubble: #eef2f9;
  --danger: #8b2331;
  --danger-bg: #fdf0f1;
  --danger-border: #f0c5ca;

  /* Tone pairs, named once. These used to be hard-coded in the component
     rules and re-hard-coded in a dark media block, which is how a palette
     drifts: two places to change and only one of them remembered. A rule
     that reads `var(--tone-bad-bg)` cannot be wrong in one theme only. */
  --tone-ok-bg: #e7f6ec;   --tone-ok-ink: #10692f;
  --tone-warn-bg: #fdf3e0; --tone-warn-ink: #8a5a00;
  --tone-bad-bg: #fdecea;  --tone-bad-ink: #b3261e;
  --tone-info-bg: #e6f4f7; --tone-info-ink: #0d5c69;
  --tone-dept-bg: #eef0fb; --tone-dept-ink: #38439b;
  --tone-bad-border: #f0c6c2;

  /* SOLID status colours. The tone pairs above are a tinted background with
     ink on it - right for a pill, wrong for a 6px dot or a 3px rule, which
     have no room for a background and need one saturated colour.
     These were hardcoded in nine component rules, and had drifted: the `ok`
     dot was #1a9c46 while the `ok` pill's ink was #10692f, so two things
     meaning "healthy" on the same screen were different greens. */
  --status-ok: #1a9c46;
  --status-warn: #b07a00;
  --status-bad: #b3261e;

  /* The rail is navy in BOTH themes, so its colours cannot come from the
     theme tokens - they are relationships to navy, not to the page. */
  --on-navy: #dbe6f5;
  --on-navy-muted: #9fb3d1;
  --on-navy-hover: rgba(255, 255, 255, .07);
  --on-navy-active: rgba(52, 181, 200, .16);
  --on-navy-strong: #ffffff;
  /* The page banner. Navy in both themes for the same reason the rail is:
     it is the product's own surface, not the page's. */
  --hero-gradient: linear-gradient(100deg, #0b1638 0%, #101f4a 55%, #0b1638 100%);
  --hero-btn-border: rgba(255, 255, 255, .28);
  --hero-btn-bg: rgba(255, 255, 255, .1);

  /* Citation source marks. Six hues that only have to be DISTINCT from each
     other - they carry no status meaning, so they are not the tone or status
     ramps and must not be mistaken for them. */
  --source-1: #4f5bd5;
  --source-2: #1a9c46;
  --source-3: #d97706;
  --source-4: #2563eb;
  --source-5: #7c3aed;
  --source-6: #0d9488;

  /* Ink on the cyan. Cyan is a brand constant, so its ink is one too - it
     cannot come from --accent-ink, which flips with the theme. */
  --on-cyan: #04263b;
  /* The QR plate stays white in both themes on purpose: a scanner needs the
     light modules light, and a transparent SVG in dark mode puts dark
     modules on a dark ground and cannot be read at all. */
  --qr-plate: #ffffff;

  /* ELEVATION. Five different shadows were written inline, all of them a
     navy at some alpha - which is a shadow the light theme can see and the
     dark theme cannot, because a navy shadow on a near-black ground is
     nothing at all. Three steps, redefined per theme. */
  --elevation-1: 0 1px 2px rgba(11, 22, 56, .06), 0 8px 24px -4px rgba(11, 22, 56, .14);   /* menus, popovers */
  --elevation-2: 0 2px 6px rgba(11, 22, 56, .06), 0 28px 56px -12px rgba(11, 22, 56, .30); /* modals */
  --elevation-3: -20px 0 48px -12px rgba(11, 22, 56, .22);                                   /* the drawer, from the right */
  --scrim: rgba(11, 22, 56, .38);

  /* ACCENT WASHES. Nine different alphas of the same cyan were in use
     (.08 .1 .12 .13 .14 .18 .25 .4 .55) for what are only three jobs:
     tint a surface, tint a border, or ring a focused control. */
  --accent-wash: rgba(52, 181, 200, .10);
  --accent-wash-strong: rgba(52, 181, 200, .18);
  --accent-edge: rgba(52, 181, 200, .40);
  --accent-ring: 0 0 0 3px rgba(52, 181, 200, .28);
  --neutral-wash: rgba(11, 22, 56, .06);
  /* The sign-in card sits on navy in both themes, so its shadow is cast on
     navy and does not flip with the page. */
  --elevation-on-navy: 0 28px 70px rgba(0, 0, 0, .32);
  --hero-glow: radial-gradient(120% 180% at 88% 50%, rgba(52, 181, 200, .28) 0%, rgba(52, 181, 200, 0) 55%);

  /* ======================================================================
     THE SCALE
     ======================================================================
     Everything below this line is a closed set. Before this existed the
     sheet carried, measured:

         41 distinct font sizes    .67 .68 .71 .72 .73 .74 .75 .76 .78 .8
                                   .82 .83 .84 .85 .86 .87 .88 .9 .92 .95 ...
         30 distinct spacings      .1 .15 .2 .25 .3 .35 .4 .45 .5 .55 .6
                                   .65 .7 .75 .8 .85 .9 1 1.1 1.15 1.25 ...
         18 border radii           5 6 7 8 9 10 11 12 13 14 15px, 50%, 999px
         10 font weights           500 550 560 600 620 640 650 660 680 700

     Nobody chose .83rem over .84rem; the second one was typed on a different
     day. The differences are below the threshold anyone can see, so they buy
     no hierarchy - they only guarantee that two things meant to match do not.
     Five of those weights the system font stack cannot even render, so 620
     and 640 and 650 were all arriving as the same pixels.

     A scale is worth having because it is SHORT. Picking from six sizes
     forces a decision about hierarchy; picking from forty-one is typing.
     ====================================================================== */

  /* Spacing. 4px base. Named by step, not by pixels, so a component says how
     much room it wants rather than restating an arithmetic. */
  --space-05: 0.125rem; /*  2 */
  --space-1: 0.25rem;   /*  4 */
  --space-2: 0.5rem;    /*  8 */
  --space-3: 0.75rem;   /* 12 */
  --space-4: 1rem;      /* 16 */
  --space-5: 1.25rem;   /* 20 */
  --space-6: 1.5rem;    /* 24 */
  --space-8: 2rem;      /* 32 */
  --space-10: 2.5rem;   /* 40 */
  --space-12: 3rem;     /* 48 */
  --space-16: 4rem;     /* 64 */

  /* Type. Named by ROLE, because the role is the decision and the size is
     the consequence - and because a screen asking for `--text-meta` cannot
     accidentally set metadata at body size. */
  --text-hero: 2.5rem;         /* the one question on an empty Ask screen */
  --text-display: 1.75rem;     /* the one number on a tile */
  --text-title: 1.375rem;      /* the page's h1 */
  --text-section: 1rem;        /* a card or section heading */
  --text-body: 0.9375rem;      /* running text, 15px */
  --text-small: 0.875rem;      /* dense text: table cells, list rows */
  --text-label: 0.8125rem;     /* form labels, buttons, tabs */
  --text-meta: 0.75rem;        /* timestamps, counts, hints */
  --text-micro: 0.6875rem;     /* eyebrows and pills, always uppercase */

  /* Weight. Four. The variable typeface could draw any weight from 200 to
     800; four is what the hierarchy needs, and a fifth is a decision nobody made. */
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* Line height. Long-form text needs room; a table row needs none. */
  --leading-tight: 1.25;
  --leading-snug: 1.4;
  --leading-normal: 1.55;

  /* Radius. A pill is a pill and a card is a card; there is no meaning
     between 11px and 12px. */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-pill: 999px;

  /* The smallest a control may be where the pointer is a finger. Measured in
     Chromium at 390px, the page actions were 34px, the mode tabs 24px and the
     header controls 38px - all of them things somebody taps first. Applied
     only below 48rem: a mouse is precise and a 44px row of buttons on a
     desktop is wasted vertical space. */
  --tap-min: 44px;
  --radius-circle: 50%;
  /* A 3px hairline marker, not a corner. Named so it is a decision rather
     than a number that escaped the scale. */
  --radius-hairline: 3px;

  /* Breakpoints cannot be custom properties - a media query cannot read one.
     They are stated here as the contract and enforced by the design-system
     test, which fails on any width not in this set:

         48rem   768px   AT AND BELOW: phone and portrait tablet
         64rem  1024px   tablet -> desktop
        100rem  1600px   the content stops growing

     A max-width query matches AT its width, so 768x1024 - a portrait tablet -
     gets the drawer rather than the rail. That is deliberate: 92px of rail
     out of 768 is worth more to the content than to the navigation, and the
     drawer holds the same nine destinations.

     Three, chosen to sit exactly on the viewports this product is tested at:
     390x844 and 768x1024 and 1024x768 and 1280x800 and 1440x900. */

  /* The rail's width, named because the shell grid and the responsive rule
     both have to agree on it. */
  --rail: 5.75rem;

  /* MOTION. Four durations and two curves, mirrored in `motion.tsx` for the
     things Framer Motion moves. Hover and press are `--motion-fast`: slower
     than that and a control feels as if it is thinking about whether to
     respond. Nothing on this appliance takes longer than `--motion-slow`. */
  --motion-instant: 80ms;
  --motion-fast: 140ms;
  --motion-base: 200ms;
  --motion-slow: 280ms;
  --ease-standard: cubic-bezier(.2, 0, 0, 1);
  --ease-exit: cubic-bezier(.3, 0, 1, 1);

  /* Container. 84rem is about 110 characters of table at this font size -
     wide enough for the widest screen the appliance has (the audit trail),
     narrow enough that a row can be read across without losing the line. */
  --page-max: 84rem;
  /* How tall a list may grow inside a card before it scrolls in place. About
     ten rows: enough to read a release history at a glance, short enough
     that one card cannot make its whole row two thousand pixels tall. */
  --scroll-max: 26rem;
  --page-pad-x: var(--space-5);
  --page-pad-y: var(--space-5);
  --shadow: 0 1px 2px rgba(11, 22, 56, 0.06), 0 4px 16px rgba(11, 22, 56, 0.05);
  --shadow-card: 0 1px 2px rgba(16, 24, 40, .04), 0 1px 3px rgba(16, 24, 40, .06);
  --scroll-thumb: #d3d9e4;
  --scroll-thumb-hover: #b9c2d2;

  font-family: "Plus Jakarta Sans", Inter, system-ui, sans-serif;
  color-scheme: light dark;
}

/* The dark palette, in one place, reachable two ways.
 *
 * `@media (prefers-color-scheme: dark)` alone cannot be overridden by a
 * control in the page, and a `[data-theme]` attribute alone ignores the
 * preference somebody already expressed to their operating system. Both, with
 * the media query standing down when a person has chosen explicitly:
 *
 *   no attribute      -> follow the system
 *   data-theme=dark   -> dark, whatever the system says
 *   data-theme=light  -> light, whatever the system says
 *
 * The values are written twice because plain CSS has no way to name a block
 * and apply it under two conditions. Everything a component needs is a token,
 * so this is the only place in the sheet that repeats. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --scroll-thumb: #2b3760;
    --scroll-thumb-hover: #3a4877;

    --bg: #070b1c;
    --surface: #0e1531;
    --surface-raised: #131c3b;
    --surface-sunken: #0a1027;
    --surface-hover: #16203f;
    --bubble-user-bg: #10304a;
    --bubble-user-border: #1d4e6b;
    --ask-blue: #4f7ff0;
    --ask-blue-hover: #6a93f3;
    --ask-blue-soft: #9db8f7;
    --ask-blue-ink: #ffffff;
    --ask-glow-1: rgba(79, 127, 240, .12);
    --ask-glow-2: rgba(139, 92, 246, .10);
      --border: #1f2a4d;
    --border-strong: #2c3a63;
    --text: #e8edf7;
    --muted: #94a1bd;

    --accent: #34b5c8;
    /* On navy the accent is already 7.22:1. Defined anyway: a colour with no
       value in one theme renders the other theme's. */
    --accent-text: #34b5c8;
    --accent-ink: #04263b;

    /* On dark, the cyan becomes the primary surface: it is the brighter of
       the two brand colours and reads clearly against the navy ground. */
    --primary: #34b5c8;
    --primary-hover: #5cc6d6;
    --primary-ink: #05192c;

    --user-bubble: #16203f;
    --danger: #ff9aa5;
    --danger-bg: #2c1119;
    --danger-border: #56222c;

    --tone-ok-bg: #10321c;   --tone-ok-ink: #7ee2a0;
    --tone-warn-bg: #38290c; --tone-warn-ink: #f3ce80;
    --tone-bad-bg: #3a1a17;  --tone-bad-ink: #ffb4a9;
    --tone-info-bg: #0e2e33; --tone-info-ink: #7fd6e3;
    --tone-dept-bg: #1b1f45; --tone-dept-ink: #a7b0ee;
    --tone-bad-border: #6b2b25;

    --status-ok: #35c46b;
    --status-warn: #d9a441;
    --status-bad: #e5675a;

    --elevation-1: 0 0 0 1px rgba(255, 255, 255, .06), 0 12px 28px -4px rgba(0, 0, 0, .55);
    --elevation-2: 0 0 0 1px rgba(255, 255, 255, .06), 0 32px 64px -12px rgba(0, 0, 0, .7);
    --elevation-3: -20px 0 48px -12px rgba(0, 0, 0, .6);
    --scrim: rgba(2, 5, 16, .62);
    --accent-wash: rgba(52, 181, 200, .14);
    --accent-wash-strong: rgba(52, 181, 200, .24);
    --accent-edge: rgba(52, 181, 200, .48);
    --accent-ring: 0 0 0 3px rgba(52, 181, 200, .34);
    --neutral-wash: rgba(255, 255, 255, .06);
    --shadow-card: 0 1px 2px rgba(0, 0, 0, .5), 0 1px 3px rgba(0, 0, 0, .4);

    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 18px rgba(0, 0, 0, 0.35);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --scroll-thumb: #2b3760;
  --scroll-thumb-hover: #3a4877;

  --bg: #070b1c;
  --surface: #0e1531;
  --surface-raised: #131c3b;
  --surface-sunken: #0a1027;
  --surface-hover: #16203f;
  --bubble-user-bg: #10304a;
  --bubble-user-border: #1d4e6b;
  --ask-blue: #4f7ff0;
  --ask-blue-hover: #6a93f3;
  --ask-blue-soft: #9db8f7;
  --ask-blue-ink: #ffffff;
  --ask-glow-1: rgba(79, 127, 240, .12);
  --ask-glow-2: rgba(139, 92, 246, .10);
  --border: #1f2a4d;
  --border-strong: #2c3a63;
  --text: #e8edf7;
  --muted: #94a1bd;

  --accent: #34b5c8;
  --accent-text: #34b5c8;
  --accent-ink: #04263b;
  --primary: #34b5c8;
  --primary-hover: #5cc6d6;
  --primary-ink: #05192c;

  --user-bubble: #16203f;
  --danger: #ff9aa5;
  --danger-bg: #2c1119;
  --danger-border: #56222c;

  --tone-ok-bg: #10321c;   --tone-ok-ink: #7ee2a0;
  --tone-warn-bg: #38290c; --tone-warn-ink: #f3ce80;
  --tone-bad-bg: #3a1a17;  --tone-bad-ink: #ffb4a9;
  --tone-info-bg: #0e2e33; --tone-info-ink: #7fd6e3;
  --tone-dept-bg: #1b1f45; --tone-dept-ink: #a7b0ee;
  --tone-bad-border: #6b2b25;

  --status-ok: #35c46b;
  --status-warn: #d9a441;
  --status-bad: #e5675a;

  --elevation-1: 0 0 0 1px rgba(255, 255, 255, .06), 0 12px 28px -4px rgba(0, 0, 0, .55);
  --elevation-2: 0 0 0 1px rgba(255, 255, 255, .06), 0 32px 64px -12px rgba(0, 0, 0, .7);
  --elevation-3: -20px 0 48px -12px rgba(0, 0, 0, .6);
  --scrim: rgba(2, 5, 16, .62);
  --accent-wash: rgba(52, 181, 200, .14);
  --accent-wash-strong: rgba(52, 181, 200, .24);
  --accent-edge: rgba(52, 181, 200, .48);
  --accent-ring: 0 0 0 3px rgba(52, 181, 200, .34);
  --neutral-wash: rgba(255, 255, 255, .06);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, .5), 0 1px 3px rgba(0, 0, 0, .4);

  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 18px rgba(0, 0, 0, 0.35);
}

:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
[hidden] { display: none !important; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

.skip {
  position: absolute; inset-inline-start: .5rem; top: -3rem; z-index: 100;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
  background: var(--primary); color: var(--primary-ink); text-decoration: none;
  font-size: var(--text-small); transition: top var(--motion-fast) var(--ease-standard);
}
.skip:focus { top: .5rem; }

/* --- shell ----------------------------------------------------------------
 * One destination and its folders do not need a rail: a bar across the top
 * carries the mark, where you are, and who you are. */

.shell { min-height: 100vh; display: flex; flex-direction: column; }
.shell__head {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-6); border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.brand {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--text); text-decoration: none;
  font-size: var(--text-body); font-weight: var(--weight-bold); letter-spacing: -.01em;
}
.brand:focus-visible { outline: none; box-shadow: var(--accent-ring); border-radius: var(--radius-sm); }
/* `--primary`, not `--brand-navy`: the tile sits on a themed surface, and
   navy on the dark header is a contrast of about 1 - the mark kept its glyph
   and lost its shape. */
.brand__mark {
  display: grid; place-items: center; width: var(--space-8); height: var(--space-8);
  border-radius: var(--radius-md); background: var(--primary); color: var(--primary-ink);
}
.brand__mark svg { width: 1.125rem; height: 1.125rem; }
.crumb {
  display: flex; align-items: center; gap: var(--space-2); min-width: 0; margin: 0;
  padding-inline-start: var(--space-4); border-inline-start: 1px solid var(--border);
  font-size: var(--text-small); color: var(--muted);
}
.crumb a { color: var(--muted); text-decoration: none; }
.crumb a:hover { color: var(--text); text-decoration: underline; }
.crumb [aria-current] { color: var(--text); font-weight: var(--weight-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shell__user { display: flex; align-items: center; gap: var(--space-3); margin-inline-start: auto; }
.avatar {
  width: 30px; height: 30px; border-radius: var(--radius-circle); flex: none;
  display: grid; place-items: center; font-size: var(--text-label); font-weight: var(--weight-semibold);
  background: var(--primary); color: var(--primary-ink); text-transform: uppercase;
}
.shell__name { font-size: var(--text-label); font-weight: var(--weight-medium); }
.shell__content { flex: 1; outline: none; }

/* --- page and cards -------------------------------------------------------- */

.page {
  width: 100%; max-width: var(--page-max); margin-inline: auto;
  padding: var(--page-pad-y) var(--page-pad-x);
  display: flex; flex-direction: column; gap: var(--space-6);
}

.hero {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 6.5rem; padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--hero-glow), var(--hero-gradient);
  color: var(--on-navy-strong);
}
.hero__mark {
  display: grid; place-items: center; flex: none;
  width: var(--space-12); height: var(--space-12); border-radius: var(--radius-md);
  background: var(--accent-wash-strong); color: var(--on-navy-strong);
}
.hero__mark svg { width: var(--space-6); height: var(--space-6); }
.hero__text { min-width: 0; margin-inline-end: auto; }
.hero__eyebrow {
  margin: 0 0 var(--space-1); font-size: var(--text-micro); font-weight: var(--weight-bold);
  text-transform: uppercase; letter-spacing: .09em; color: var(--brand-cyan);
}
.hero__title { margin: 0; font-size: var(--text-title); font-weight: var(--weight-semibold); line-height: 1.15; overflow-wrap: anywhere; }
.hero__subtitle { margin: var(--space-2) 0 0; font-size: var(--text-small); line-height: 1.5; color: var(--on-navy); max-width: 62ch; }
.hero__subtitle code { font-size: var(--text-label); color: var(--on-navy-strong); }
.hero__actions { display: flex; gap: var(--space-2); align-items: center; flex: none; flex-wrap: wrap; min-height: 2.25rem; }
.hero__actions .btn { border-color: var(--hero-btn-border); background: var(--hero-btn-bg); color: var(--on-navy-strong); }
.hero__actions .btn:hover:not(:disabled) { background: var(--on-navy-hover); border-color: var(--hero-btn-border); color: var(--on-navy-strong); }
.hero__actions .btn--primary { background: var(--brand-cyan); border-color: var(--brand-cyan); color: var(--on-cyan); }
.hero__actions .btn--primary:hover:not(:disabled) { background: var(--brand-cyan); border-color: var(--brand-cyan); color: var(--on-cyan); filter: brightness(1.06); }

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.card__head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border);
}
.card__title { margin: 0; font-size: var(--text-section); font-weight: var(--weight-semibold); line-height: var(--leading-tight); }
.card__hint { margin: var(--space-1) 0 0; font-size: var(--text-meta); color: var(--muted); }
.card__body { padding: var(--space-5); }
.card--flush > .card__body { padding: 0; }

/* --- controls -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 2.25rem; padding: 0 var(--space-4);
  border-radius: var(--radius-md); border: 1px solid var(--border-strong);
  background: var(--surface); color: var(--text); cursor: pointer;
  font: inherit; font-size: var(--text-label); font-weight: var(--weight-semibold);
  line-height: 1; white-space: nowrap; text-decoration: none;
  transition:
    background-color var(--motion-fast) var(--ease-standard),
    border-color var(--motion-fast) var(--ease-standard),
    color var(--motion-fast) var(--ease-standard),
    box-shadow var(--motion-fast) var(--ease-standard),
    transform var(--motion-instant) var(--ease-standard);
}
.btn:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--border-strong); }
.btn:active:not(:disabled) { transform: scale(.98); }
.btn:focus-visible { outline: none; box-shadow: var(--accent-ring); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { flex: none; width: 1rem; height: 1rem; }
.btn--primary { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); }
.btn--primary:hover:not(:disabled) { background: var(--primary-hover); border-color: var(--primary-hover); }
.btn--danger { color: var(--tone-bad-ink); border-color: var(--tone-bad-border); background: var(--tone-bad-bg); }
.btn--danger:hover:not(:disabled) { color: var(--tone-bad-ink); background: var(--tone-bad-bg); border-color: var(--status-bad); }
.btn--ghost { background: none; border-color: var(--border); color: var(--text); }
.btn--ghost:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--border-strong); }
.btn--sm { min-height: 1.875rem; padding: 0 var(--space-3); font-size: var(--text-meta); }
.btn--block { width: 100%; }
.btn[aria-busy="true"] { cursor: progress; }
.btn .spinner { width: 14px; height: 14px; border-width: 2px; }
.btn--primary .spinner { border-color: var(--primary-ink); border-top-color: transparent; }

.iconbtn {
  display: inline-grid; place-items: center; flex: none;
  width: 2.25rem; height: 2.25rem; padding: 0;
  border: 1px solid transparent; border-radius: var(--radius-md);
  background: none; color: var(--muted); cursor: pointer;
  transition: background-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard);
}
.iconbtn:hover { background: var(--surface-hover); color: var(--text); }
.iconbtn:focus-visible { outline: none; box-shadow: var(--accent-ring); }
.iconbtn svg { width: 1rem; height: 1rem; }
.iconbtn--danger:hover { background: var(--tone-bad-bg); color: var(--tone-bad-ink); }

.field { display: flex; flex-direction: column; gap: var(--space-1); }
.field__label { font-size: var(--text-label); font-weight: var(--weight-semibold); }
.field__hint { margin: 0; font-size: var(--text-meta); color: var(--muted); }
.field__hint code { font-size: var(--text-meta); color: var(--text); }
.stack { display: flex; flex-direction: column; gap: var(--space-4); }
.field__error { margin: 0; font-size: var(--text-label); color: var(--danger); }

.input {
  min-height: 2.25rem; padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface); color: inherit; font: inherit; font-size: var(--text-small);
  width: 100%;
  transition: border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard);
}
.input:hover:not(:disabled):not(:focus) { border-color: var(--muted); }
.input::placeholder { color: var(--muted); }
.input:focus { outline: none; border-color: var(--brand-cyan); box-shadow: var(--accent-ring); }
.input[aria-invalid="true"] { border-color: var(--status-bad); }

.searchfield { position: relative; display: flex; align-items: center; min-width: 0; flex: 0 1 16rem; }
.searchfield__icon { position: absolute; inset-inline-start: var(--space-3); display: grid; place-items: center; color: var(--muted); pointer-events: none; }
.searchfield__icon svg { width: 1rem; height: 1rem; }
.searchfield .input { padding-inline-start: var(--space-10); }
.listbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); }
.listbar__count { margin: 0 auto 0 0; font-size: var(--text-meta); color: var(--muted); white-space: nowrap; }

/* --- states ---------------------------------------------------------------- */

.state {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  padding: var(--space-12) var(--space-4); text-align: center;
}
.state__mark {
  display: grid; place-items: center; width: var(--space-12); height: var(--space-12);
  margin-bottom: var(--space-2); border-radius: var(--radius-lg);
  background: var(--surface-sunken); color: var(--muted);
}
.state__mark svg { width: var(--space-6); height: var(--space-6); }
.state--error .state__mark { background: var(--tone-bad-bg); color: var(--tone-bad-ink); }
.state__title { margin: 0; font-weight: var(--weight-semibold); font-size: var(--text-section); }
.state__detail { margin: 0; color: var(--muted); font-size: var(--text-small); max-width: 34rem; }
.state--loading { flex-direction: row; justify-content: center; color: var(--muted); font-size: var(--text-small); }
.state--error .state__title { color: var(--danger); }
.state__action { margin-top: var(--space-2); }
.spinner {
  width: 15px; height: 15px; border-radius: var(--radius-circle);
  border: 2px solid var(--border); border-top-color: var(--brand-cyan);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.pill {
  display: inline-flex; align-items: center; gap: var(--space-1);
  padding: var(--space-05) var(--space-2); border-radius: var(--radius-pill);
  font-size: var(--text-meta); font-weight: var(--weight-semibold); line-height: var(--leading-snug);
  border: 1px solid transparent; white-space: nowrap;
}
.pill--ok   { background: var(--tone-ok-bg); color: var(--tone-ok-ink); }
.pill--warn { background: var(--tone-warn-bg); color: var(--tone-warn-ink); }
.pill--bad  { background: var(--tone-bad-bg); color: var(--tone-bad-ink); }
.pill--idle { background: var(--surface-sunken); color: var(--muted); border-color: var(--border); }

/* --- tables ------------------------------------------------------------------
 * A table that is wider than the screen scrolls inside its own box, never the
 * page. */

.table-scroll { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: var(--text-small); }
.table thead th {
  text-align: start; font-size: var(--text-micro); font-weight: var(--weight-semibold);
  text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
  padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border);
  background: var(--surface-sunken); white-space: nowrap;
}
.table tbody td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background-color var(--motion-fast) var(--ease-standard); }
.table tbody tr:hover td { background: var(--surface-hover); }
.table__num, .table th.table__num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table__muted { color: var(--muted); white-space: nowrap; }
.table__actions, .table th.table__actions { text-align: end; white-space: nowrap; }
.datatable__title {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--text); font-weight: var(--weight-semibold); text-decoration: none;
  /* `break-word`, not `anywhere`: inside a table cell `anywhere` lets the
     column shrink to one character, and a file name read down the page. */
  overflow-wrap: break-word; min-width: 0;
}
.table td:first-child { min-width: 12rem; }
a.datatable__title:hover { text-decoration: underline; }
a.datatable__title:focus-visible { outline: none; box-shadow: var(--accent-ring); border-radius: var(--radius-sm); }
.datatable__icon {
  display: grid; place-items: center; flex: none; width: var(--space-8); height: var(--space-8);
  border-radius: var(--radius-md); background: var(--accent-wash); color: var(--accent-text);
}
.datatable__icon svg { width: 1rem; height: 1rem; }
.datatable__folder { display: block; margin-top: var(--space-05); padding-inline-start: var(--space-10); font-size: var(--text-meta); color: var(--muted); font-weight: var(--weight-regular); }

/* --- file drop ------------------------------------------------------------------------------ */

.filedrop {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  padding: var(--space-8) var(--space-4); text-align: center;
  border: 2px dashed var(--border-strong); border-radius: var(--radius-lg);
  background: var(--surface-sunken);
  transition: border-color var(--motion-fast) var(--ease-standard), background-color var(--motion-fast) var(--ease-standard);
}
.filedrop.is-over { border-color: var(--brand-cyan); background: var(--accent-wash); }
.filedrop__mark {
  display: grid; place-items: center; width: var(--space-12); height: var(--space-12);
  border-radius: var(--radius-circle); background: var(--surface); color: var(--accent-text);
  border: 1px solid var(--border);
}
.filedrop__mark svg { width: var(--space-6); height: var(--space-6); }
.filedrop__title { margin: var(--space-1) 0 0; font-size: var(--text-section); font-weight: var(--weight-semibold); color: var(--text); }
.filedrop__hint { margin: 0 0 var(--space-2); max-width: 28rem; font-size: var(--text-meta); color: var(--muted); }

.uploads { list-style: none; margin: var(--space-4) 0 0; padding: 0; display: flex; flex-direction: column; }
.uploads__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3);
  padding: var(--space-2) 0; border-bottom: 1px solid var(--border);
}
.uploads__row:last-child { border-bottom: 0; }
.uploads__name { flex: 1; min-width: 0; font-size: var(--text-small); color: var(--text); overflow-wrap: anywhere; }
.uploads__reason { flex: 1 1 100%; margin: 0; font-size: var(--text-meta); color: var(--tone-bad-ink); }
.uploads__note { flex: 1 1 100%; margin: 0; font-size: var(--text-meta); color: var(--muted); }

/* --- modal ----------------------------------------------------------------- */

.modal__scrim {
  position: fixed; inset: 0; background: var(--scrim);
  display: grid; place-items: center; padding: var(--space-4); z-index: 50;
}
.modal {
  width: min(30rem, 100%); max-height: 88vh; overflow: auto;
  background: var(--surface-raised); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--elevation-2);
}
.modal__head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) var(--space-4) var(--space-4) var(--space-6);
}
.modal__head h2 { margin: 0; font-size: var(--text-section); font-weight: var(--weight-semibold); }
.modal__body {
  padding: 0 var(--space-6) var(--space-5); display: flex; flex-direction: column; gap: var(--space-4);
  font-size: var(--text-small); line-height: var(--leading-normal);
}
.modal__body > p { margin: 0; color: var(--muted); }
.modal__foot {
  display: flex; justify-content: flex-end; gap: var(--space-2);
  padding: var(--space-4) var(--space-6); border-top: 1px solid var(--border);
  background: var(--surface-sunken); border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* --- toasts ---------------------------------------------------------------- */

.toasts {
  position: fixed; inset-inline-end: var(--space-5); bottom: var(--space-5); z-index: 60;
  display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-2);
  pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: var(--space-3);
  min-width: 18rem; max-width: 26rem; padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border); border-inline-start: 3px solid var(--brand-cyan); border-radius: var(--radius-lg);
  background: var(--surface-raised); color: var(--text); box-shadow: var(--elevation-1);
  font-size: var(--text-small); line-height: var(--leading-snug);
  pointer-events: auto; overflow-wrap: anywhere;
}
.toast--ok { border-inline-start-color: var(--status-ok); }
.toast--bad { border-inline-start-color: var(--status-bad); }

/* --- sign-in ----------------------------------------------------------------- */

.login { min-height: 100vh; display: grid; place-items: center; padding: var(--space-6); background: var(--brand-navy); }
.login__card {
  width: min(24rem, 100%); display: flex; flex-direction: column; gap: var(--space-4);
  padding: var(--space-6); border-radius: var(--radius-lg); background: var(--surface);
  box-shadow: var(--elevation-on-navy);
}
.login__brand { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-2); }
.login__powered {
  font-size: var(--text-micro); font-weight: var(--weight-semibold);
  text-transform: uppercase; letter-spacing: .09em; color: var(--muted);
}
.login__brand picture { display: block; width: min(11rem, 70%); }
.login__logo { width: 100%; height: auto; display: block; }
.login__title { margin: 0; font-size: var(--text-title); font-weight: var(--weight-semibold); line-height: var(--leading-tight); }
.login__lede { margin: 0; font-size: var(--text-small); color: var(--muted); line-height: 1.45; }
.login__error { margin: 0; font-size: var(--text-label); color: var(--danger); }
.login__footnote { margin: 0; font-size: var(--text-meta); color: var(--muted); text-align: center; }
.login__aside { display: none; }
@media (min-width: 64rem) {
  .login:has(> .login__aside) { grid-template-columns: minmax(0, 28rem) minmax(0, 24rem); justify-content: center; column-gap: var(--space-16); }
  .login__aside { display: flex; flex-direction: column; gap: var(--space-8); color: var(--on-navy); }
}
.login__aside-title {
  margin: 0; font-size: var(--text-display); font-weight: var(--weight-bold);
  line-height: var(--leading-tight); letter-spacing: -.02em; color: var(--on-navy-strong);
}
.login__points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-5); }
.login__points li { display: flex; align-items: flex-start; gap: var(--space-3); font-size: var(--text-body); line-height: var(--leading-normal); }
.login__points svg { flex: none; width: 1.25rem; height: 1.25rem; margin-top: var(--space-05); color: var(--brand-cyan); }

/* --- narrow viewports ----------------------------------------------------------
 * Last in the sheet on purpose: same specificity, later wins. */

@media (max-width: 48rem) {
  .shell__head { padding: var(--space-3) var(--space-4); gap: var(--space-3); flex-wrap: wrap; }
  .crumb { order: 3; flex: 1 1 100%; padding-inline-start: 0; border-inline-start: 0; }
  .shell__name, .shell__label { display: none; }
  .page { padding: var(--space-4); gap: var(--space-4); }
  .hero { flex-wrap: wrap; padding: var(--space-5); gap: var(--space-4); }
  .hero__mark { display: none; }
  .hero__actions { flex: 1 1 100%; }
  .hero__actions .btn { flex: 1 1 auto; }
  .listbar { padding: var(--space-3) var(--space-4); }
  .searchfield { flex: 1 1 100%; }
  .login { padding: var(--space-4); }
  .toasts { inset-inline: var(--space-4); align-items: stretch; }
  .toast { min-width: 0; max-width: none; }
  .table__optional { display: none; }
  .btn, .iconbtn, .input { min-height: var(--tap-min); }
  .iconbtn { width: var(--tap-min); height: var(--tap-min); }
  .btn--sm { min-height: var(--tap-min); }
  .brand, .crumb a { min-height: var(--tap-min); display: inline-flex; align-items: center; }
  .modal__foot { flex-direction: column-reverse; }
  .modal__foot .btn { width: 100%; }
}
