/* Simple Modern Design Language — Simple Modern Support.

   ONE stylesheet shared in spirit by every product: calm and white-dominant,
   the system SF stack, hairline borders, gentle shadows, generous whitespace,
   and exactly ONE accent per product (Simple Modern Support green). The token block below is
   identical in both product repositories apart from that accent ramp — if you
   change a value here, change it there.

   Light and dark are both first class: the palette follows the reader's system
   setting via prefers-color-scheme, and an explicit data-theme on <html> wins
   in either direction. Every token is defined on bare :root first, so nothing
   depends on a media query having matched. */

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

:root {
  color-scheme: light;

  /* surfaces */
  --canvas: #f3f5f7;
  --sunken: #f3f5f7;
  --card: #ffffff;
  --side: #ffffff;
  --field: #ffffff;

  /* hairlines — the only borders this language draws */
  --hair: #dfe3e8;
  --hair-soft: #e8ebef;
  --ring: var(--accent);

  /* ink */
  --ink: #111418;
  --ink-2: #3d4550;
  /* Same failing grey as --ink-3 carried under a second name: the token was
     changed and the pages did not, because most quiet text reads --muted.
     Kept in step deliberately — two names for one ink must not drift. */
  --muted: #616a7b;

  /* interaction */
  --hover: #f3f5f7;
  --selected: var(--accent-soft);
  --btn2: #f8f9fb;

  /* chrome surfaces — what the shared shell (smdl-shell.css) paints with */
  --surface: #ffffff;
  --surface-2: #f8f9fb;
  --surface-3: #eef1f4;
  /* Measured against every light surface this token is painted on: at #6b7488 it
     failed WCAG AA (4.5:1) on five of six — surface-2 4.19, surface-3 3.93,
     good-soft 4.17, bad-soft 4.10, warn-soft 4.27. #616a7b clears all of them,
     worst case 4.57 on surface-3. Dark mode already passes and is untouched.
     Changed in all six siblings together: the family's own test asserts that
     nothing but the accent differs between products. */
  --ink-3: #616a7b;

  /* status — the same three hues in both products, used sparingly */
  --good: #08764f;  --good-soft: #e6f4ee;
  --bad: #b3261e;   --bad-soft: #fbeae8;
  --warn: #8a5a06;  --warn-soft: #fdf3e3;

  /* THE ONE THING A PRODUCT CHANGES — this application's seat colour, in the
     six variants the design language allows. tile fills shapes 16px and up;
     ink is coloured TEXT on light and clears 4.5:1; deep is that ink taken
     down until it clears 4.5:1 on soft, which is what a status pill needs;
     soft is a light tint of this same hue for selected rows; sidebar is the
     deep cut that paints the whole navigation rail, where white text clears
     14:1; dark is this hue lifted for a near-black surface — never a
     different hue.
     Simple Modern Support is green. */
  --accent: #159A5C;
  --accent-ink: #0F854F;
  --accent-deep: #037846;
  --accent-soft: #D8EFDF;
  --accent-quiet: rgba(21, 154, 92, 0.10);
  --on-accent: #ffffff;
  /* The rail is the room: the same deep cut on a light canvas and a dark one,
     with the seat lit in the lifted variant because the rail IS near-black. */
  --app-sidebar: #03331C;
  --app-dark: #5FC88C;
  --live: var(--accent-deep);
  --live-soft: var(--accent-soft);

  /* elevation, radii, type */
  --shadow-card: 0 0 0 1px var(--hair);
  --shadow-pop: 0 8px 24px rgba(17,19,24,.08);
  /* The shell declares these too, and loads after this file — so declaring a
     different value here meant this stylesheet's geometry never applied. Same
     values, stated once per product so the token is visible where it is used. */
  --radius: 8px;
  --radius-sm: 6px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto,
          Helvetica, Arial, "Helvetica Neue", sans-serif;

  /* v6 (DESIGN.md §3) */
  --line: #dfe3e8;
  --line-strong: #c3cad3;
  --line-soft: #e8ebef;
  --mark-quiet: #c8cfd8;
  --inset: #f3f5f7;
  --ink-4: #838c98;
  --ok: #08764f;
  --ok-soft: #e6f4ee;
  --danger: #b3261e;
  --danger-soft: #fbeae8;
  --info: #476780;
  --info-soft: #e9eff4;
  --off: #838c98;
  --off-soft: #eef1f4;
  --scrim: rgba(45,49,47,.40);
  --shadow-dlg: 0 18px 48px rgba(17,19,24,.14);
  --radius-lg: 10px;
  --radius-badge: 4px;
  --row: 44px;
  --row-dense: 40px;
  --row-two: 48px;
  --ctl: 32px;
  --ctl-dense: 28px;
  --ctl-lg: 36px;
  --w-fly-s: 400px;
  --w-fly-m: 480px;
  --w-fly-l: 640px;
  --pane: 380px;
  --pane-head: 44px;
  --pane-foot: 36px;
  --ease: cubic-bezier(.2,0,0,1);
  --dur-fly: 180ms;
  --dur-scrim: 120ms;
  --dur-exit: 120ms;
  --dur-swap: 90ms;
  --dur-toast: 160ms;
  --z-menu: 900;
  --z-fly: 1000;
  --z-confirm: 1050;
  --z-toast: 1100;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --canvas: #0c1016;
    --sunken: #10151d;
    --card: #151a23;
    --side: #151a23;
    --field: #10151d;

    --hair: #1f2630;
    --hair-soft: #1a2029;
    --ring: var(--accent);

    --ink: #edf0f6;
    --ink-2: #ccd4e2;
    --muted: #98a2b6;

    --hover: #1b212b;
    --selected: var(--accent-soft);
    --btn2: #1b212b;

    /* chrome surfaces — what the shared shell (smdl-shell.css) paints with */
    --surface: #151a23;
    --surface-2: #1b212b;
    --surface-3: #222937;
    --ink-3: #98a2b6;

    --good: #5fc88c;  --good-soft: #12251c;
    --bad: #fc6474;   --bad-soft: #2c1417;
    --warn: #e3b341;  --warn-soft: #2a2311;

    /* The accent lifts for a dark canvas — the same hue, not a different one.
       Leaving --accent at its light value made every filled control muddy. */
    --accent: #5FC88C;
    --accent-ink: #5FC88C;
    --accent-deep: var(--accent-ink);
    --accent-soft: #112A1B;
    --accent-quiet: rgba(95, 200, 140, 0.16);
    --on-accent: #03331C;
    --app-sidebar: #03331C;
    --app-dark: #5FC88C;

    --shadow-card: 0 0 0 1px var(--hair);
    --shadow-pop: 0 8px 24px rgba(0,0,0,.45);
  
  /* v6 (DESIGN.md §3) */
  --line: #1f2630;
  --line-strong: #2c3542;
  --line-soft: #1a2029;
  --mark-quiet: #39424f;
  --inset: #10151d;
  --ink-4: #6b7688;
  --ok: #5fc88c;
  --ok-soft: #12251c;
  --danger: #fc6474;
  --danger-soft: #2c1417;
  --info: #8fa9be;
  --info-soft: #18222b;
  --off: #6b7688;
  --off-soft: #1b212b;
  --scrim: rgba(0,0,0,.55);
  --shadow-dlg: 0 18px 48px rgba(0,0,0,.6);
}
}

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

  --canvas: #0c1016;
  --sunken: #10151d;
  --card: #151a23;
  --side: #151a23;
  --field: #10151d;

  --hair: #1f2630;
  --hair-soft: #1a2029;
  --ring: var(--accent);

  --ink: #edf0f6;
  --ink-2: #ccd4e2;
  --muted: #98a2b6;

  --hover: #1b212b;
  --selected: var(--accent-soft);
  --btn2: #1b212b;

  /* chrome surfaces — what the shared shell (smdl-shell.css) paints with */
  --surface: #151a23;
  --surface-2: #1b212b;
  --surface-3: #222937;
  --ink-3: #98a2b6;

  --good: #5fc88c;  --good-soft: #12251c;
  --bad: #fc6474;   --bad-soft: #2c1417;
  --warn: #e3b341;  --warn-soft: #2a2311;

  /* The accent lifts for a dark canvas — the same hue, not a different one.
     Leaving --accent at its light value made every filled control muddy. */
  --accent: #5FC88C;
  --accent-ink: #5FC88C;
  --accent-deep: var(--accent-ink);
  --accent-soft: #112A1B;
  --accent-quiet: rgba(95, 200, 140, 0.16);
  --on-accent: #03331C;
  --app-sidebar: #03331C;
  --app-dark: #5FC88C;

  --shadow-card: 0 0 0 1px var(--hair);
  --shadow-pop: 0 8px 24px rgba(0,0,0,.45);

  /* v6 (DESIGN.md §3) */
  --line: #1f2630;
  --line-strong: #2c3542;
  --line-soft: #1a2029;
  --mark-quiet: #39424f;
  --inset: #10151d;
  --ink-4: #6b7688;
  --ok: #5fc88c;
  --ok-soft: #12251c;
  --danger: #fc6474;
  --danger-soft: #2c1417;
  --info: #8fa9be;
  --info-soft: #18222b;
  --off: #6b7688;
  --off-soft: #1b212b;
  --scrim: rgba(0,0,0,.55);
  --shadow-dlg: 0 18px 48px rgba(0,0,0,.6);
}

html, body { max-width: 100%; overflow-x: hidden; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--smdl-text-body);
  line-height: var(--smdl-leading-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: none; }
h1, h2, h3, h4 { letter-spacing: normal; font-weight: var(--smdl-weight-semibold); line-height: var(--smdl-leading-heading); margin: 0; }
h1 { font-size: var(--smdl-text-heading); }
h2, h3, h4 { font-size: var(--smdl-text-section); }
b, strong { font-weight: var(--smdl-weight-semibold); }
p { margin: 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }

code, .mono { font-family: var(--mono); font-size: var(--smdl-text-meta); }
code { background: var(--selected); border-radius: 5px; padding: 1px 5px; }

/* ------------------------------------------------------------------ shell */

/* The shell grid, corner switcher, top bar, sidebar and canvas all come from
   smdl-shell.css — the SAME file CORE serves, so the family is one chrome by
   construction. This stylesheet keeps only what the shell does not carry: the
   profile popover, the signed-out header, and this product's page furniture. */

.avatar {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  background: var(--accent-quiet); color: var(--accent-deep);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 680; letter-spacing: 0;
}

/* profile popover — mirrors CORE's, on this stylesheet's tokens */
.user-menu { position: relative; }
.user-pop {
  position: absolute; top: calc(100% + 8px); right: 0;
  min-width: 260px; padding: 8px; border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--shadow-pop);
  z-index: 60;
}
.user-pop[hidden] { display: none; }
.user-pop-id { display: flex; align-items: center; gap: 11px; padding: 10px 10px 14px; }
.user-pop-who { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.user-pop-who b { font-size: var(--smdl-text-body); }
.user-pop-who small { color: var(--ink-3); font-size: var(--smdl-text-meta); overflow: hidden; text-overflow: ellipsis; }
.user-pop-appearance { padding: 2px 10px 16px; }
.user-pop-label { display: block; color: var(--ink-3); font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); margin-bottom: 8px; }
/* The same segmented control as everywhere else — see .smdl-seg in the shared
   shell for why the radii are concentric and why the chosen segment is lifted
   rather than filled with the accent. This carried its own numbers (8 and 6,
   against CORE's 999 and 999 for the same control), which is how one product's
   theme switcher came to look like a different component from another's. */
.theme-seg {
  display: flex; width: 100%; padding: 3px; gap: 2px;
  border: 0; box-shadow: inset 0 0 0 1px var(--hair);
  border-radius: var(--radius-sm); background: var(--surface-2);
}
.theme-seg button {
  flex: 1; height: 28px; padding: 0; border: 0; border-radius: var(--radius-badge, 4px);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: none; color: var(--ink-2); font-family: var(--sans);
  font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium); line-height: var(--smdl-leading-body); cursor: pointer;
  transition: background .14s ease, color .14s ease, box-shadow .14s ease;
}
.theme-seg button:hover { color: var(--ink); }
.theme-seg button:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.theme-seg button[aria-pressed="true"] {
  background: var(--card); color: var(--ink); font-weight: var(--smdl-weight-semibold);
  box-shadow: 0 0 0 1px var(--hair), 0 1px 2px rgba(16, 24, 40, .06);
}
.theme-seg button .ic { width: 15px; height: 15px; font-size: 15px; }
@media (prefers-reduced-motion: reduce) { .theme-seg button { transition: none; } }
.user-pop-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  border: 0; background: none; font-family: var(--sans); font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium);
  color: var(--ink-2); padding: 9px 10px; border-radius: var(--radius-sm);
  cursor: pointer; text-decoration: none;
}
.user-pop-item .ic { font-size: 16px; opacity: 0.7; }
.user-pop-item:hover { background: var(--surface-2); color: var(--ink); }
.user-pop-item.danger-item:hover { color: var(--bad); background: var(--bad-soft); }
.user-pop form { margin: 0; }

/* the signed-out header (landing and error surfaces) */
.brand {
  display: flex; align-items: center; gap: 9px;
  font-weight: var(--smdl-weight-semibold); letter-spacing: normal; color: var(--ink);
  padding: 5px 8px; border-radius: var(--radius-sm);
}
.brand:hover { background: var(--hover); }
.mark { width: 24px; height: 24px; flex: none; }
.plain-actions { margin-left: auto; display: flex; gap: 8px; }

/* the page inside the shell canvas */
.page { max-width: 1180px; margin: 0 auto; padding: 0 4px 64px; }

/* A create or edit form is a single column of fields, and 760px is where that
   column stays comfortable to fill in -- a 1180px-wide input for a 200-character
   title helps nobody. The cap itself was right and was already in use, as an
   inline style repeated across ten templates. What was wrong is WHERE it sat:
   hard against the left of the 1180px measure, with 400px of nothing beside it
   on pages whose only content is that one card. It is centred in the measure
   now, and named, so the next form does not have to rediscover the number. */
.formpage { max-width: var(--measure-form, 760px); margin-inline: auto; }

/* ----------------------------------------------------------------- pieces */

.card {
  background: var(--card); border-radius: var(--radius);
  box-shadow: var(--shadow-card); padding: 20px;
}
.card + .card { margin-top: 16px; }
/* Design law: boxes that share a grid are spaced by the grid alone — the
   stacked-card margin above must never knock side-by-side cards off level. */
.split > .card, .stats > .card { margin-top: 0; }
.card h2 { font-size: var(--smdl-text-section); margin-bottom: 4px; }
.card .card-sub { color: var(--muted); font-size: var(--smdl-text-meta); }
.card-flush { padding: 0; overflow: hidden; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: var(--smdl-control-height); height: auto; padding: var(--smdl-control-pad) 13px; border: 1px solid var(--hair);
  border-radius: var(--ctl-radius, 9px); background: var(--card); color: var(--ink);
  font-family: var(--sans); font-weight: var(--smdl-weight-medium); font-size: var(--smdl-text-control);
  cursor: pointer; white-space: nowrap;
}
.btn:hover { background: var(--hover); }
/* A filled control carries text, so it takes the deeper step of the hue:
   the tile itself clears 4.5:1 against white in only four of the six
   products. --accent stays the graphical value. */
.btn-primary { background: var(--accent-deep); border-color: transparent; color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-deep); filter: brightness(1.06); }
.btn-quiet { background: transparent; border-color: transparent; color: var(--muted); }
.btn-quiet:hover { background: var(--hover); color: var(--ink); }
/* The destructive variant. Eight controls in this product carried .btn-danger
   -- revoke a connection, delete a field, cancel a change, reject an approval
   -- and no stylesheet defined it, so every one of them rendered as an
   ordinary button. An action that cannot be undone has to look like one
   BEFORE it is pressed. Outlined rather than filled: the danger is in the
   consequence, not in the frequency, and a wall of solid red trains people to
   ignore it. */
.btn-danger {
  color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, var(--hair));
  background: var(--card);
}
.btn-danger:hover { background: var(--bad-soft); border-color: var(--bad); }
.btn-danger:focus-visible { outline: 2px solid var(--bad); outline-offset: 1px; }
/* Used in table cells to keep a date or a ref on one line. Also never defined. */
.nowrap { white-space: nowrap; }
.btn-sm { min-height: var(--smdl-control-small); height: auto; padding: 6px 10px; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium); }
/* A pressed toggle in a row of buttons — the notification inbox's All / Unread.
   Same selected state the bell panel's tabs wear. */
.btn.is-active { background: var(--accent-soft); border-color: transparent; color: var(--accent-ink); }

/* The summary row reads the whole desk — every kind, problems included —
   while the list beneath it is requests and incidents. Unlabelled, its "open"
   sat above a shorter list and looked like a miscount. */
.stats-cap {
  margin: 0 0 8px; font-size: var(--smdl-text-meta); line-height: var(--smdl-leading-body); font-weight: var(--smdl-weight-medium);
  letter-spacing: normal; text-transform: none; color: var(--ink-3);
}
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px;
  margin-bottom: 20px; }
.stat {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow-card);
  padding: 15px 16px;
}
/* The number over its label, not beside it. Both were left inline, so the
   first page to use this pair rendered "6Received". */
.stat .n { display: block; font-size: var(--smdl-text-metric); font-weight: var(--smdl-weight-semibold); letter-spacing: normal; line-height: var(--smdl-leading-heading); }
.stat .k { display: block; color: var(--muted); font-size: var(--smdl-text-meta); margin-top: 2px; }
.stat.is-accent .n { color: var(--accent-ink); }

/* filters */
.filters {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-bottom: 14px;
}
.filters select, .filters input[type="search"], .filters input[type="text"] {
  width: auto; height: 32px; border: 1px solid var(--hair); border-radius: var(--radius-sm);
  background: var(--card); color: var(--ink); font-family: var(--sans); font-size: var(--smdl-text-control);
  padding: 0 10px; min-width: 0; font-weight: var(--smdl-weight-regular);
}
.filters input[type="search"] { min-width: 190px; flex: 1 1 190px; max-width: 320px; }

/* tables scroll inside themselves; the page never scrolls sideways */
.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.list { width: 100%; border-collapse: collapse; font-size: var(--smdl-text-body); min-width: 640px; }
table.list th {
  text-align: left; font-size: var(--smdl-text-meta); text-transform: none; letter-spacing: normal;
  color: var(--muted); font-weight: var(--smdl-weight-medium); padding: 12px 16px; border-bottom: 1px solid var(--hair-soft);
  white-space: nowrap;
}
table.list td { padding: 13px 16px; border-bottom: 1px solid var(--hair-soft); vertical-align: middle; }
table.list tr:last-child td { border-bottom: 0; }
table.list tbody tr:hover { background: var(--hover); }
table.list .ref { font-family: var(--mono); font-size: var(--smdl-text-meta); color: var(--muted); white-space: nowrap; }
table.list .subject { font-weight: var(--smdl-weight-medium); color: var(--ink); }
table.list .subject a:hover { color: var(--accent-ink); }
table.list .num { text-align: right; font-variant-numeric: tabular-nums; }
table.list .when { color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Ticket subjects are the primary scan target. Reserve 220px of readable
   text plus cell padding; the queue scrolls locally before that space is
   sacrificed to an assignee address or the persistent claim control. */
.ticket-queue { min-width: 0; max-width: 100%; }
.ticket-table-wrap { position: relative; min-width: 0; max-width: 100%; overscroll-behavior-x: contain; }
.ticket-table-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
table.ticket-table { min-width: 1120px; }
table.ticket-table .subject { min-width: 252px; width: 28%; overflow-wrap: anywhere; }
table.ticket-table .ref { white-space: nowrap; }
table.ticket-table .ticket-assignee { min-width: 160px; }
.ticket-assignee > span { display: block; max-width: 200px; overflow-wrap: anywhere; }
/* A capped list says so — the same honesty as the dashboard's bounded pass. */
.listcap { margin: 0; padding: 12px 16px; border-top: 1px solid var(--hair-soft);
  color: var(--muted); font-size: var(--smdl-text-meta); }
/* A queue used to stop dead at its limit, with the count beside it naming a
   larger number and nothing on the page able to reach the rest. */
.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; padding: 12px 16px; border-top: 1px solid var(--hair-soft); }
.pager-count { margin: 0; padding: 12px 16px; color: var(--muted); font-size: var(--smdl-text-meta); }
.pager .pager-count { padding: 0; }
.pager-links { display: flex; gap: 8px; }
.pager .btn.is-disabled { opacity: .5; pointer-events: none; }

/* chips */
/* A BADGE, NOT A PILL. The chip was a 999px capsule at 650 weight, which is
   the one shape on the page that says "tap me" without being tappable -- and
   next to a card at 8px and a control at 6px it was the only fully round thing
   left. It is the mockup's badge now: the shared badge radius, a shorter box,
   and the weight down to 500, because the tint is what carries a status and
   the label does not also have to shout. The four custom properties stay, so
   a context that needs a bigger chip still says so in one place. */
.chip {
  display: inline-flex; align-items: center; gap: 5px; height: var(--chip-h, 20px);
  padding: 0 var(--chip-pad, 6px); border-radius: var(--radius-badge); font-size: var(--smdl-text-meta);
  font-weight: var(--chip-fw, 500); letter-spacing: normal;
  background: var(--selected); color: var(--ink-2); white-space: nowrap;
}
.chip .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.chip-accent { background: var(--accent-quiet); color: var(--accent-deep); }
.chip-quiet { background: transparent; color: var(--muted); border: 1px solid var(--hair); }
/* Priority and state read by weight, not by a second hue: the accent marks
   what is urgent and everything else stays neutral. */
.chip-p1 { background: var(--accent); color: var(--on-accent); }
.chip-p2 { background: var(--accent-quiet); color: var(--accent-deep); }
/* The queue's Target column: the same three status hues the dashboard's meter
   uses, so "past target" reads identically everywhere it is said. */
.chip-late { background: var(--bad-soft); color: var(--bad); }
.chip-soon { background: var(--warn-soft); color: var(--warn); }

.pill-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* forms */
.field { display: block; margin-bottom: 14px; }
.field > .label {
  display: block; font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); color: var(--ink-2); margin-bottom: 5px;
}
.field .help { font-size: var(--smdl-text-meta); color: var(--muted); margin-top: 5px; }
/* Time and number inputs fell outside this list entirely and rendered as raw
   browser controls beside styled ones — on Business hours, which is nothing
   but times and numbers. */
input[type="text"], input[type="email"], input[type="date"], input[type="search"],
input[type="time"], input[type="number"], input[type="url"], input[type="password"],
input[type="file"], select, textarea {
  width: 100%; border: 1px solid var(--hair); border-radius: var(--radius-sm);
  background: var(--card); color: var(--ink); font-family: var(--sans); font-size: var(--smdl-text-control);
  padding: 8px 11px; max-width: 100%; font-weight: var(--smdl-weight-regular);
}
textarea { min-height: 120px; resize: vertical; line-height: 1.55; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: transparent; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 16px; }
.form-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.checkline { display: flex; align-items: center; gap: 8px; font-size: var(--smdl-text-body); color: var(--ink-2); }
.checkline input { width: auto; }
/* A list of checklines framed like the field it replaces; long lists scroll
   inside it rather than stretching the form. */
.checkgroup {
  display: flex; flex-direction: column; gap: 8px; max-height: 240px; overflow-y: auto;
  border: 1px solid var(--hair); border-radius: var(--radius-sm); padding: 10px 11px;
  background: var(--card);
}

/* inline control forms on a detail page */
.control { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.control select { flex: 1 1 140px; height: 32px; padding: 0 10px; }

/* the composer's canned-reply picker: one quiet row above the textarea */
.canned-row { display: flex; gap: 10px; align-items: center; margin-bottom: 10px; }
.canned-row select { flex: 0 1 260px; height: 30px; padding: 0 10px; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-regular); }
.canned-row .text-link { white-space: nowrap; }

/* two-column detail layout */
.split { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px; align-items: start; }
.aside { display: flex; flex-direction: column; gap: 16px; }
.aside .card h2 { font-size: var(--smdl-text-section); text-transform: none; letter-spacing: normal;
  color: var(--muted); margin-bottom: 12px; }

.kv { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 8px 10px; font-size: var(--smdl-text-body); }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }

/* thread */
.thread { display: flex; flex-direction: column; gap: 12px; }
.note { border: 1px solid var(--hair-soft); border-radius: var(--radius); padding: 14px 16px;
  background: var(--card); }
.note.internal { background: var(--sunken); border-style: dashed; }
.note .who { display: flex; align-items: center; gap: 8px; font-size: var(--smdl-text-meta); margin-bottom: 7px; }
.note .who b { font-weight: var(--smdl-weight-semibold); }
.note .who .when { color: var(--muted); margin-left: auto; }
.note .body { white-space: pre-wrap; color: var(--ink-2); line-height: 1.6; overflow-wrap: anywhere; }

/* banners */
.banner {
  display: flex; gap: 10px; align-items: flex-start; padding: 11px 14px; border-radius: var(--radius-sm);
  font-size: var(--smdl-text-body); margin-bottom: 16px; border: 1px solid var(--hair);
}
/* A refusal was a grey hairline and a success was painted in the product's
   accent, so "Saved." shouted and "That is not a date." whispered — the two
   exactly the wrong way round. Status colour comes from the status tokens, and
   a blocking warning gets the third one rather than reading as an aside. */
.banner-ok { background: var(--good-soft); border-color: transparent; color: var(--good); }
.banner-err { background: var(--bad-soft); border-color: transparent; color: var(--bad);
  font-weight: var(--smdl-weight-medium); }
.banner-warn { background: var(--warn-soft); border-color: transparent; color: var(--warn);
  font-weight: var(--smdl-weight-medium); }
.banner-info { background: var(--sunken); color: var(--ink-2); }

.empty { text-align: left; padding: 34px 20px; color: var(--muted); }
.empty h2 { font-size: var(--smdl-text-section); color: var(--ink); margin-bottom: 6px; }
.empty p { max-width: 60ch; }

/* article reader */
.reader { max-width: 68ch; }
.reader h2 { font-size: var(--smdl-text-section); margin: 26px 0 8px; }
.reader h3 { font-size: var(--smdl-text-section); margin: 20px 0 6px; }
.reader p { margin: 0 0 12px; color: var(--ink-2); line-height: 1.68; }
.reader ul { margin: 0 0 14px; padding-left: 22px; }
.reader li { margin: 0 0 8px; color: var(--ink-2); line-height: 1.68; }
.reader > :first-child { margin-top: 0; }

/* ------------------------------------------------- landing and standalone */

.plain { min-height: 100vh; display: flex; flex-direction: column; }
.plain-top { display: flex; align-items: center; gap: 12px; padding: 18px 24px; flex-wrap: wrap; }
.landing { width: 100%; max-width: 660px; margin: 0 auto; padding: 72px 24px 96px; }
.landing h1 { font-size: var(--smdl-text-heading); line-height: var(--smdl-leading-heading); font-weight: var(--smdl-weight-semibold); letter-spacing: normal;
  margin-bottom: 16px; }
.landing .lede { font-size: var(--smdl-text-body); line-height: var(--smdl-leading-body); color: var(--ink-2); margin-bottom: 28px; }
.ctas { display: flex; gap: 10px; flex-wrap: wrap; }
.cta {
  display: inline-flex; align-items: center; height: 40px; padding: 0 19px;
  border-radius: var(--radius-sm); background: var(--accent); color: var(--on-accent);
  font: inherit; font-weight: var(--smdl-weight-medium); font-size: var(--smdl-text-control); border: 1px solid transparent;
  cursor: pointer;
}
.cta.ghost { background: var(--card); color: var(--ink); border-color: var(--hair); }
.hint { margin-top: 26px; color: var(--muted); font-size: var(--smdl-text-meta); }
.orglist { display: flex; flex-direction: column; gap: 8px; margin: 26px 0 0; }
.orglist a {
  display: flex; align-items: center; gap: 10px; padding: 13px 16px; border-radius: var(--radius);
  background: var(--card); box-shadow: var(--shadow-card); font-weight: var(--smdl-weight-medium);
}
.orglist a:hover { box-shadow: var(--shadow-pop); }
.orglist a .go { margin-left: auto; color: var(--muted); font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); }

/* ------------------------------------------------------------ responsive */

/* 1280 and up gets the full three-zone shell above. */

@media (max-width: 1080px) {
  .split { grid-template-columns: minmax(0, 1fr); }
  .aside { flex-direction: row; flex-wrap: wrap; }
  .aside > .card { flex: 1 1 260px; }
}

/* 834 — tablet: the shell rail is handled by smdl-shell.css. */
@media (max-width: 900px) {
  .page { padding: 0 0 56px; }
}

/* 390 — phone. */
@media (max-width: 640px) {
  .page { padding: 0 0 48px; }
  .landing { padding: 44px 18px 72px; }
  .landing h1 { font-size: var(--smdl-text-heading); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kv { grid-template-columns: 84px minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ------------------------------------------------ public surfaces (/f, /portal) */

/* No shell, no session: a brand band in this application's deep cut, one calm
   column of cards, and a quiet foot. The band is the room the way the sidebar
   is the room inside the app. */
.pub { min-height: 100vh; display: flex; flex-direction: column; background: var(--sunken); }
.pub-band {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--app-sidebar); color: #fff; padding: 14px 22px;
}
.pub-lockup { display: flex; align-items: center; gap: 10px; min-width: 0; }
.pub-lockup .mark { width: 26px; height: 26px; }
.pub-lockup .seatgrid .lit { fill: var(--app-dark); }
.pub-lockup .seatgrid .dim { fill: rgba(255, 255, 255, 0.28); }
.pub-org { font-weight: var(--smdl-weight-semibold); letter-spacing: normal; font-size: var(--smdl-text-body);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pub-desk { color: rgba(255, 255, 255, 0.62); font-size: var(--smdl-text-meta); white-space: nowrap; }
.pub-main { flex: 1 1 auto; width: 100%; }
.pub-col { width: 100%; max-width: 640px; margin: 0 auto; padding: 28px 16px 48px;
  display: flex; flex-direction: column; }
.pub-col > .card, .pub-col form > .card { margin-top: 14px; }
.pub-col > :first-child { margin-top: 0; }
.pub-foot { text-align: center; color: var(--muted); font-size: var(--smdl-text-meta); padding: 18px 16px 26px; }

.pub-cover h1 { font-size: var(--smdl-text-heading); letter-spacing: normal; }
.pub-desc { color: var(--ink-2); font-size: var(--smdl-text-body); line-height: var(--smdl-leading-body); margin-top: 8px; }
.pub-hours { margin-top: 12px; }
.pub-ok { color: var(--accent-ink); font-size: 26px; margin-bottom: 6px; }
.pub-ref { margin-top: 14px; color: var(--ink-2); font-size: var(--smdl-text-meta); }

.pub-field .pub-label { display: block; font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); }
.pub-field .pub-hint { color: var(--muted); font-size: var(--smdl-text-meta); margin-top: 3px; }
.pub-field input, .pub-field select, .pub-field textarea { margin-top: 10px; }
.pub-req { color: var(--accent-ink); }
.pub-field.has-error { box-shadow: var(--shadow-card), inset 0 0 0 1.5px var(--bad); }
.pub-error { color: var(--bad); font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); margin-top: 6px; }

/* Choice fields are big option cards: the whole row is the target, and the
   picked one wears the accent — readable from arm's length on a phone. */
.pub-options { display: grid; gap: 8px; margin-top: 12px; border: 0; padding: 0; margin-inline: 0; }
/* Published knowledge, read by the people it was written for. */
.portal-kb { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 8px; }
.portal-kb a { color: var(--accent-ink); font-weight: var(--smdl-weight-medium); }
.portal-kb a:hover { text-decoration: underline; }
.article-body { white-space: pre-wrap; line-height: 1.7; color: var(--ink-2);
  max-width: 72ch; overflow-wrap: anywhere; }
/* Named for a screen reader, invisible to everyone else. */
.vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
/* The refusal summary: every failing answer, each one a jump to its own field. */
.pub-errorlist { margin: 8px 0 0; padding-left: 18px; display: grid; gap: 4px; }
.pub-errorlist a { color: inherit; font-weight: var(--smdl-weight-semibold); text-decoration: underline; }
.pub-option {
  display: flex; align-items: center; gap: 10px; padding: 12px 14px;
  border: 1px solid var(--hair); border-radius: var(--radius-sm);
  background: var(--card); cursor: pointer; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium);
}
.pub-option:hover { background: var(--hover); }
.pub-option input { width: auto; margin: 0; accent-color: var(--accent); }
.pub-option:has(input:checked) {
  border-color: transparent; background: var(--accent-soft); color: var(--accent-ink);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}
.pub-send { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
.pub-send-btn { height: 40px; padding: 0 22px; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium); }
.pub-send-note { color: var(--muted); font-size: var(--smdl-text-meta); }
/* The honeypot: gone from view and from the tab order, present in the DOM. */
.pub-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* the requester portal */
.pub-bandform { display: flex; align-items: center; gap: 10px; }
.pub-bandbtn {
  appearance: none; border: 1px solid rgba(255, 255, 255, 0.28); background: transparent;
  color: #fff; font: inherit; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium); cursor: pointer;
  padding: 5px 11px; border-radius: 999px;
}
.pub-bandbtn:hover { background: rgba(255, 255, 255, 0.12); }
.portal-back { margin: 0 0 2px; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium); }
.portal-back a { color: var(--muted); font-weight: var(--smdl-weight-medium); }
.portal-back a:hover { color: var(--accent-ink); }
.portal-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.portal-row:hover { box-shadow: var(--shadow-pop); }
.portal-row-main { display: grid; gap: 2px; min-width: 0; }
.portal-row-main b { font-size: var(--smdl-text-body); font-weight: var(--smdl-weight-semibold); overflow-wrap: anywhere; }
.portal-row-main small { color: var(--muted); font-size: var(--smdl-text-meta); }
.portal-row-side { display: grid; gap: 4px; justify-items: end; flex: none; }
.portal-row-side small { color: var(--muted); font-size: var(--smdl-text-meta); white-space: nowrap; }
/* Your own words sit on the app's soft tint, the desk's on the card. */
.note.portal-mine { background: var(--accent-soft); border-color: transparent; }

/* ----------------------------------------------------- channels & builder */

/* A box that shares a grid is spaced by the grid alone: these cards were
   taking the stacked-card margin as well, so Channels sat at 32px while every
   aside sat at 16px. */
.chan-grid { display: grid; gap: 16px; }
.chan-grid > .card { margin-top: 0; }
.chan-sub { font-size: var(--smdl-text-meta); text-transform: none; letter-spacing: normal;
  color: var(--muted); margin-top: 18px; }
.chan-callers { list-style: none; display: flex; gap: 8px; flex-wrap: wrap;
  margin: 12px 0 0; padding: 0; }
.builder-rowtools { display: flex; gap: 4px; }
.builder-rowtools form { margin: 0; }
.sharecode {
  margin: 10px 0 0; padding: 12px; background: var(--sunken); border-radius: var(--radius-sm);
  border: 1px solid var(--hair-soft); overflow-x: auto; font-size: var(--smdl-text-meta); line-height: var(--smdl-leading-body);
}
.sharecode code { background: none; padding: 0; white-space: pre-wrap; overflow-wrap: anywhere; }

/* ------------------------------------------------------ the page heading */

/* Every page opens the same way: a quiet eyebrow in this application's ink
   naming the part of the desk you are standing in, one large title, and one
   calm line. The eyebrow is written in sentence case; only the stylesheet
   shouts. */
.pagehead { margin: 0 0 22px; max-width: 76ch; }
/* The skip link lands here; the jump itself needs no ring. */
.pagehead:focus { outline: none; }
/* Context, not the headline. This shouted -- 11.5px uppercase in the accent,
   tracked out a tenth of an em -- because for a while it was the only text at
   the top of the page: the title it was meant to sit above was being hidden by
   the shell. With the title visible again, an eyebrow that still shouts simply
   competes with it. */
.pagehead .eyebrow {
  color: var(--ink-3); font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium);
  letter-spacing: normal; text-transform: none; margin-bottom: 6px;
}
/* The title moved to the shell's own heading, where every sibling puts it, so
   this block is now the eyebrow and the line beneath it — and collapses to
   nothing on a page that has neither. */
.pagehead:empty { display: none; margin: 0; }
.pagehead .eyebrow:last-child { margin-bottom: 0; }
.pagehead .lede { color: var(--muted); font-size: var(--smdl-text-body); line-height: var(--smdl-leading-body); }

/* A card that carries a heading, a line of explanation, and something on the
   right — a count, a control. */
.card-head { display: flex; align-items: flex-start; gap: 12px; }
/* Junk / Not junk was decided from a subject line, with the message body
   nowhere on the page. */
.quarantine-peek { margin-top: 6px; }
.quarantine-peek summary { cursor: pointer; color: var(--accent-ink); font-size: var(--smdl-text-control);
  font-weight: var(--smdl-weight-medium); }
.quarantine-peek .note-body { margin-top: 8px; padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--sunken); color: var(--ink-2); font-size: var(--smdl-text-body); line-height: var(--smdl-leading-body);
  white-space: pre-wrap; max-width: 68ch; overflow-wrap: anywhere; }
/* A flush card puts its own padding back around the heading, and only there:
   the table below it still runs to the card's edge. */
.card-flush .card-head { padding: 20px 20px 0; }
.card-flush .card-head + .tablewrap { margin-top: 14px; }
.card-head > div { min-width: 0; }
/* The push-right belongs to a SECOND child — a count, a control. On a card
   whose head is just a heading and a line, `> :last-child` was the heading's
   own wrapper, so it was shoved to the right edge and its subtitle wrapped
   into a narrow column against nothing. */
.card-head > :first-child { flex: 1 1 auto; }
.card-head > :last-child:not(:first-child) { margin-left: auto; flex: none; }
.stack { min-width: 0; }

/* ------------------------------------------------------- the workstream */

/* One ranked list of the work that needs a person, each row carrying the
   reason it is here. A queue that only sorts is a queue you have to re-derive
   in your head. */
.workstream { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 2px; }
.work {
  display: grid; gap: 3px; padding: 11px 12px; border-radius: var(--radius-sm);
  border: 1px solid transparent;
}
.work:hover { background: var(--hover); }
.work.is-late { background: var(--bad-soft); }
.work.is-late:hover { background: var(--bad-soft); border-color: var(--hair); }
.work-title { font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); color: var(--ink); overflow-wrap: anywhere; }
.work-title:hover { color: var(--accent-ink); }
.work-meta {
  display: flex; flex-wrap: wrap; gap: 4px 10px; color: var(--muted); font-size: var(--smdl-text-meta);
}
.work-why { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.why {
  display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 9px;
  border-radius: 999px; font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); white-space: nowrap;
  background: var(--selected); color: var(--ink-2);
}
.why .ic { font-size: 13px; }
.why-bad { background: var(--bad-soft); color: var(--bad); }
.why-warn { background: var(--warn-soft); color: var(--warn); }

/* ------------------------------------------------------------- the rail */

/* The Today rail: small figures and short lists, never a second queue. */
.rail h2 { font-size: var(--smdl-text-section); }
.rail-figures {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px;
  margin: 14px 0 0; padding: 0;
}
.rail-figures div { min-width: 0; }
.rail-figures dt { color: var(--muted); font-size: var(--smdl-text-meta); }
.rail-figures dd {
  margin: 1px 0 0; font-size: var(--smdl-text-metric); font-weight: var(--smdl-weight-semibold); letter-spacing: normal;
  font-variant-numeric: tabular-nums;
}
.rail-label {
  margin: 18px 0 8px; font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); text-transform: none;
  letter-spacing: normal; color: var(--muted);
}
.rail-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.rail-list li { display: grid; gap: 1px; }
.rail-list a { font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); overflow-wrap: anywhere; }
.rail-list a:hover { color: var(--accent-ink); }
.rail-list small { color: var(--muted); font-size: var(--smdl-text-meta); }
.rail-none { color: var(--muted); font-size: var(--smdl-text-meta); margin-top: 8px; }
.rail-none a { color: var(--accent-ink); font-weight: var(--smdl-weight-semibold); }
.rail-foot { margin-top: 16px; color: var(--muted); font-size: var(--smdl-text-meta); }

/* A meter, not a chart: proportions of one whole, in the three status hues
   with the app's own colour standing for healthy. */
.meter {
  display: flex; gap: 2px; height: 8px; margin-top: 14px; border-radius: 999px;
  overflow: hidden; background: var(--selected);
}
.meter span { display: block; min-width: 3px; }
.meter-late { background: var(--bad); }
.meter-soon { background: var(--warn); }
.meter-ok { background: var(--accent); }
.meter-rest { background: var(--selected); }

/* --- Getting started guide -------------------------------------------------- */
/* The desk teaches until it is real: a checklist whose every step is a fact
   about this organization's rows, in the same card idiom as everything else. */
.card.guide { padding: 0; }
.guide-summary {
  display: flex; align-items: center; gap: 10px; min-height: 52px;
  padding: 12px 16px; list-style: none; cursor: pointer;
  border-radius: inherit;
}
.guide-summary::-webkit-details-marker { display: none; }
.guide-summary > strong { min-width: 0; font-size: var(--smdl-text-body); font-weight: var(--smdl-weight-semibold); }
.guide-summary > .ic:first-child { color: var(--accent-ink); }
.guide-summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.guide-count { font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium); white-space: nowrap;
  font-variant-numeric: tabular-nums; color: var(--muted); }
.guide-count small { font-size: inherit; font-weight: inherit; }
.guide-chevron { margin-left: auto; color: var(--muted); }
.guide[open] > .guide-summary .guide-chevron { transform: rotate(180deg); }
.guide-body { padding: 16px 20px 20px; border-top: 1px solid var(--hair-soft); }
.guide + .filters { margin-top: 20px; }
.guide-meter { margin-top: 16px; }
.guide-steps { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 2px; }
.guide-steps li { display: flex; align-items: flex-start; gap: 11px; padding: 9px 10px;
  border-radius: var(--radius-sm); }
.guide-steps li:hover { background: var(--hover); }
.guide-steps li.is-done .g-body a { color: var(--muted); }
.guide-steps .g-mark {
  width: 18px; height: 18px; flex: none; margin-top: 1px; border-radius: 50%;
  border: 1.5px solid var(--hair); display: inline-flex; align-items: center;
  justify-content: center; color: var(--on-accent); font-size: 11px;
}
.guide-steps li.is-done .g-mark { background: var(--accent); border-color: transparent; }
.guide-steps .g-body { display: grid; gap: 1px; min-width: 0; }
.guide-steps .g-body a { font-weight: var(--smdl-weight-semibold); font-size: var(--smdl-text-body); }
.guide-steps .g-body a:hover { color: var(--accent-ink); }
.guide-steps .g-body small { color: var(--muted); font-size: var(--smdl-text-meta); }
.guide-dismiss { margin-top: 14px; }

/* Platform notifications: a quick triage panel in the shell and a full inbox
   in the canvas. The event store is in CORE; this product only renders the
   signed-in person's deliveries and sends read state back through its own
   authenticated server. */
.platform-notif { position: relative; }
.platform-notif-bell { position: relative; }
.platform-notif-badge {
  position: absolute; top: 1px; right: 1px; min-width: 15px; height: 15px;
  padding: 0 4px; border-radius: 999px; background: var(--accent); color: var(--on-accent);
  box-shadow: 0 0 0 2px var(--canvas); font-size: var(--smdl-text-meta); line-height: var(--smdl-leading-body);
  text-align: center; font-weight: var(--smdl-weight-medium);
}
.platform-notif-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 90; width: min(390px, calc(100vw - 28px));
  overflow: hidden; border-radius: var(--radius-lg); background: var(--card);
  box-shadow: 0 0 0 1px var(--hair), 0 20px 54px -18px rgba(8, 11, 16, .42);
}
.platform-notif-panel[hidden] { display: none; }
.platform-notif-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: 48px; padding: 0 14px; border-bottom: 1px solid var(--hair-soft);
}
.platform-notif-head strong { font-size: var(--smdl-text-body); }
.text-link {
  appearance: none; border: 0; padding: 4px; background: none; color: var(--accent-ink);
  font: inherit; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium); cursor: pointer;
}
.platform-notif-tabs { display: flex; gap: 4px; padding: 8px 10px; border-bottom: 1px solid var(--hair-soft); }
.platform-notif-tabs button {
  appearance: none; border: 0; border-radius: var(--radius-sm); padding: 6px 10px; background: transparent;
  color: var(--muted); font: inherit; font-size: var(--smdl-text-control); font-weight: var(--smdl-weight-medium); cursor: pointer;
}
.platform-notif-tabs button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent-ink); }
.platform-notif-list { max-height: min(430px, 58vh); overflow-y: auto; }
.platform-notif-item {
  display: grid; grid-template-columns: 8px minmax(0, 1fr) auto; gap: 10px; align-items: start;
  padding: 12px 14px; color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--hair-soft);
}
.platform-notif-item:hover { background: var(--surface-2); }
.platform-notif-item .notif-dot { width: 7px; height: 7px; margin-top: 5px; border-radius: 50%; background: transparent; }
.platform-notif-item.is-unread .notif-dot { background: var(--accent); }
.platform-notif-copy { min-width: 0; }
.platform-notif-copy strong, .platform-notif-copy small { display: block; }
.platform-notif-copy strong { font-size: var(--smdl-text-body); font-weight: var(--smdl-weight-semibold); overflow-wrap: anywhere; }
.platform-notif-copy small { margin-top: 3px; color: var(--muted); font-size: var(--smdl-text-meta); line-height: var(--smdl-leading-body); overflow-wrap: anywhere; }
.platform-notif-source { color: var(--muted); font-size: var(--smdl-text-meta); text-transform: none; letter-spacing: normal; }
.platform-notif-empty { padding: 28px 16px; color: var(--muted); text-align: center; font-size: var(--smdl-text-body); }
.platform-notif-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 11px 14px; color: var(--accent-ink); text-decoration: none; font-size: var(--smdl-text-meta); font-weight: var(--smdl-weight-medium);
}
.notification-feed { display: grid; gap: 0; }
.notification-feed .platform-notif-item { grid-template-columns: 8px minmax(0, 1fr) auto; padding: 15px 16px; }
.notification-feed .platform-notif-item:last-child { border-bottom: 0; }

@media (max-width: 640px) {
  .platform-notif-panel { position: fixed; top: 58px; right: 10px; left: 10px; width: auto; }
  .platform-notif-item, .notification-feed .platform-notif-item {
    grid-template-columns: 8px minmax(0, 1fr);
  }
  .platform-notif-source { grid-column: 2; }
}
