/* ============================================================
   WAEW OS — portal design system
   Ethereal glass: OLED ground, mesh light, vantablack glass cards
   sitting in machined trays. Every surface is a nested enclosure.

   Phone first. Everything below 768px is one column with a bottom bar;
   the same rules widen on a desktop. Tap targets are 44px on a phone.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&family=Geist+Mono:wght@400;500&display=swap');

:root{
  /* Every colour in the app is built from these bases. A look changes the
     bases; nothing below this block names a colour directly. Alphas stay
     exactly as designed, so a light look is the same glass on a different
     ground rather than a second design. */
  color-scheme:dark;

  /* ground */
  --void:#050505;
  --core:#0b0b0d;
  --fg-rgb:255,255,255;          /* what glass, hairlines and hover are tinted with */
  --tray:rgba(var(--fg-rgb),.035);
  --core-hi:rgba(var(--fg-rgb),.055);

  /* hairlines — never a 1px solid grey */
  --edge:rgba(var(--fg-rgb),.08);
  --edge-soft:rgba(var(--fg-rgb),.045);
  --edge-lit:rgba(var(--fg-rgb),.16);

  /* ink */
  --ink:#f4f4f5;
  --ink-rgb:244,244,245;
  --ink-2:rgba(var(--ink-rgb),.62);
  --ink-3:rgba(var(--ink-rgb),.38);
  --ink-4:rgba(var(--ink-rgb),.22);

  /* one accent, spent carefully */
  --lum:#8ef0c4;
  --lum-rgb:142,240,196;
  --lum-dim:rgba(var(--lum-rgb),.14);
  --lum-line:rgba(var(--lum-rgb),.32);
  --lum-hover:#a4f5d2;
  --on-lum:#04150d;              /* text on the accent */
  --on-lum-rgb:4,21,13;
  --acc:#c4c3ff;                 /* the second tint: avatars, "replied" */
  --acc-rgb:126,124,255;

  /* semantic, separate from the accent */
  --warn:#f5c26b;
  --warn-rgb:245,194,107;
  --warn-dim:rgba(var(--warn-rgb),.13);
  --crit:#ff8f8f;
  --crit-rgb:255,143,143;
  --crit-dim:rgba(var(--crit-rgb),.12);

  /* chrome glass: rail, menu, phone bar, toast */
  --rail-bg:rgba(10,10,12,.72);
  --sheet-bg:rgba(12,12,14,.9);
  --bar-bg:rgba(8,8,10,.86);
  --toast-bg:rgba(12,12,14,.92);

  /* the light behind everything, and the film grain on top */
  --mesh-1:rgba(var(--lum-rgb),.10);
  --mesh-2:rgba(var(--acc-rgb),.09);
  --mesh-3:rgba(var(--lum-rgb),.05);
  --grain:.028;

  /* shadows: dark looks can afford deep ones, light looks cannot */
  --shadow-rgb:0,0,0;
  --shadow-k:1;

  --r-shell:2rem;
  --r-core:calc(2rem - .375rem);
  --ease:cubic-bezier(.32,.72,0,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  /* the phone bottom bar, without the home-indicator inset. Everything
     that must clear it (page padding, toast, menu sheet) derives from
     this one number, so they can never drift apart. */
  --bar-h:3.6rem;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
/* The `hidden` attribute must win over any display a class sets (.btn is
   inline-flex, .row is flex/grid) — without this, hidden buttons stay visible. */
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--void);
  color:var(--ink);
  font-family:'Geist','Plus Jakarta Sans',system-ui,sans-serif;
  font-size:15px;
  line-height:1.55;
  font-feature-settings:'ss01','cv05';
  -webkit-font-smoothing:antialiased;
}
/* Nothing may pan the page sideways. `clip` rather than `hidden`: hidden
   turns body into a scroll container, which silently breaks position:sticky
   for every descendant. Root causes are fixed below; this is the backstop. */
html,body{max-width:100%;overflow-x:hidden;overflow-x:clip}

/* mesh light — fixed, never inside a scroller */
body::before{
  content:'';position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(48rem 32rem at 12% -8%, var(--mesh-1), transparent 62%),
    radial-gradient(40rem 30rem at 96% 6%, var(--mesh-2), transparent 60%),
    radial-gradient(56rem 40rem at 62% 108%, var(--mesh-3), transparent 66%);
}
/* film grain — fixed pseudo-element only */
body::after{
  content:'';position:fixed;inset:0;z-index:1;pointer-events:none;opacity:var(--grain);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------- type */
h1,h2,h3,h4{margin:0;font-weight:500;letter-spacing:-.028em;text-wrap:balance;overflow-wrap:anywhere}
h1{font-size:clamp(2.1rem,5vw,3.1rem);line-height:1.03}
h2{font-size:clamp(1.4rem,3vw,1.85rem);line-height:1.12}
h3{font-size:1.02rem;letter-spacing:-.014em;font-weight:500}
p{margin:0}
.mono{font-family:'Geist Mono',ui-monospace,monospace;font-variant-numeric:tabular-nums;letter-spacing:-.02em}

.eyebrow{
  display:inline-flex;align-items:center;gap:.45rem;max-width:100%;
  padding:.3rem .7rem;border-radius:999px;
  background:var(--tray);border:1px solid var(--edge-soft);
  font-size:10px;text-transform:uppercase;letter-spacing:.2em;font-weight:500;color:var(--ink-3);
}
.eyebrow .dot{width:4px;height:4px;border-radius:50%;background:var(--lum);box-shadow:0 0 8px var(--lum);flex:0 0 auto}

/* ---------------------------------------------------- double-bezel */
.shell{
  background:var(--tray);
  border:1px solid var(--edge-soft);
  border-radius:var(--r-shell);
  padding:.375rem;
  min-width:0;max-width:100%;
}
.core{
  background:var(--core);
  border:1px solid var(--edge);
  border-radius:var(--r-core);
  box-shadow:inset 0 1px 1px rgba(var(--fg-rgb),.055);
  padding:1.5rem;
  height:100%;
  min-width:0;max-width:100%;
}
.core.tight{padding:1.1rem 1.25rem}

/* ---------------------------------------------------------- frame */
.frame{position:relative;z-index:2;min-height:100dvh;display:flex;flex-direction:column}

/* ----------------------------------------------------------- rail
   Desktop: one floating pill, centred — brand · tabs · gear. It is
   centred with auto margins rather than a transform so the menu sheet
   can anchor to the gear (anchor positioning ignores transforms). */
.rail{
  position:fixed;top:1.5rem;left:0;right:0;margin:0 auto;z-index:60;
  width:max-content;max-width:calc(100vw - 2rem);
  background:var(--rail-bg);backdrop-filter:blur(28px) saturate(1.6);
  -webkit-backdrop-filter:blur(28px) saturate(1.6);
  border:1px solid var(--edge);border-radius:999px;
  padding:.35rem;display:flex;align-items:center;gap:.2rem;
  box-shadow:0 18px 50px -24px rgba(var(--shadow-rgb),calc(.9 * var(--shadow-k)));
}
.rail .brand{
  display:flex;align-items:center;gap:.5rem;padding:.4rem .85rem .4rem .7rem;
  font-weight:600;letter-spacing:-.03em;font-size:.9rem;white-space:nowrap;flex:0 0 auto;
}
.rail .brand a{color:inherit;text-decoration:none}
.rail .brand em{font-style:normal;color:var(--ink-3);font-weight:400}
/* the area menu on the brand (People & Admin, 29 Oct 2026) */
.rail .brand.has-menu{position:relative;padding:0}
.rail .brand-b{appearance:none;border:0;background:transparent;color:inherit;font:inherit;font-weight:600;letter-spacing:-.03em;padding:.4rem .7rem;border-radius:999px;cursor:pointer;display:flex;align-items:center;gap:.3rem;white-space:nowrap}
.rail .brand-b:hover,.rail .brand-b[aria-expanded="true"]{background:rgba(var(--fg-rgb),.07)}
.rail .brand-b .caret{display:inline-grid;place-items:center;width:.9rem;height:.9rem;transform:rotate(-90deg);opacity:.6}
.rail .brand-b .caret svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.rail .brand-b[aria-expanded="true"] .caret{transform:rotate(90deg)}
.area-menu[hidden]{display:none}
.area-menu{position:absolute;top:calc(100% + .4rem);left:0;min-width:14rem;padding:.35rem;border-radius:14px;background:var(--bg,#0b0b0c);border:1px solid var(--edge);box-shadow:0 12px 40px rgba(0,0,0,.35);z-index:60;display:flex;flex-direction:column;gap:2px}
.area-menu .tab{width:100%;justify-content:flex-start;display:flex;gap:.6rem;align-items:center;padding:.55rem .7rem;border-radius:10px;font-size:.85rem;font-weight:500;letter-spacing:0}
.area-menu .tab svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:0 0 auto}
.area-menu .tab[aria-selected="true"]{background:rgba(var(--fg-rgb),.08);color:var(--ink)}
/* The nav may shrink but never spill over the gear: if a label set ever
   outgrows the rail (font substitution, browser zoom) it scrolls sideways
   with the scrollbar hidden instead of overlapping. The padding and
   negative margin keep the focus ring from being clipped. */
.rail nav{display:flex;gap:.1rem;min-width:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;padding:.3rem;margin:-.3rem}
.rail nav::-webkit-scrollbar{display:none}
.tab{
  appearance:none;border:0;background:transparent;color:var(--ink-3);
  font:inherit;font-size:.83rem;font-weight:450;
  padding:.5rem .85rem;border-radius:999px;cursor:pointer;white-space:nowrap;flex:0 0 auto;
  transition:color .5s var(--ease), background .5s var(--ease);
}
.tab:hover{color:var(--ink)}
.tab[aria-selected="true"]{background:rgba(var(--fg-rgb),.07);color:var(--ink)}
/* an unread count on a tab, a bar button or a sheet item */
.pip{
  display:inline-block;margin-left:.4rem;min-width:1.05rem;padding:0 .28rem;
  border-radius:999px;background:var(--crit-dim);color:var(--crit);
  font-size:10px;font-weight:600;line-height:1.05rem;text-align:center;white-space:nowrap;
}
.avatar{
  width:1.85rem;height:1.85rem;border-radius:999px;flex:0 0 auto;
  background:linear-gradient(145deg,rgba(var(--lum-rgb),.22),rgba(var(--acc-rgb),.16));
  border:1px solid var(--edge-lit);
  display:grid;place-items:center;font-size:.66rem;font-weight:600;letter-spacing:.02em;
}
/* the gear: settings, who you are, sign out — one button, one sheet */
.rail .gear{
  appearance:none;border:0;cursor:pointer;font:inherit;color:var(--ink-2);
  display:flex;align-items:center;justify-content:center;gap:.45rem;flex:0 0 auto;
  margin-left:.35rem;padding:.25rem .3rem .25rem .7rem;
  border-left:1px solid var(--edge-soft);background:transparent;border-radius:999px;
  transition:color .4s var(--ease);
}
.rail .gear svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:0 0 auto}
.rail .gear:hover{color:var(--ink)}
.rail .gear[aria-expanded="true"]{color:var(--lum)}

/* --------------------------------------------------------- corner
   Round glass controls in the top-right corner, level with the rail and
   exactly its height (OS.corner draws them: the reload button, then the
   bug and request flag). --corner is the rail's own sum — 1px border and
   .35rem padding, twice, around the gear (a 1.85rem avatar with .25rem
   padding, twice); the phone block below redoes it for the phone rail.
   Change the rail, change this.
   A second control sits a gap to the left of the first: .c2 on it, and
   .two-corners on <html> (views-app.js sets both when two are drawn) makes
   --corners, the width the rail gives up, both controls and the gap.
   On a desktop the centred rail keeps clear of the corner on both sides;
   on a phone the rail gives up the corner's width on its right. OS.corner
   puts .has-corner on <html>, so this works where :has() does not. */
:root{--corner:calc(1.85rem + .5rem + .7rem + 2px);--corner-gap:.5rem;--corners:var(--corner)}
:root.two-corners{--corners:calc(2 * var(--corner) + var(--corner-gap))}
/* three (22 Oct 2026): the help button, left of the reload button; views-guide.js sets .three-corners */
:root.three-corners{--corners:calc(3 * var(--corner) + 2 * var(--corner-gap))}
.corner{
  appearance:none;cursor:pointer;font:inherit;color:var(--ink-2);padding:0;
  position:fixed;z-index:60;top:1.5rem;right:1.5rem;width:var(--corner);height:var(--corner);
  display:grid;place-items:center;border-radius:999px;
  background:var(--rail-bg);backdrop-filter:blur(28px) saturate(1.6);-webkit-backdrop-filter:blur(28px) saturate(1.6);
  border:1px solid var(--edge);
  box-shadow:0 18px 50px -24px rgba(var(--shadow-rgb),calc(.9 * var(--shadow-k)));
  transition:color .4s var(--ease), border-color .4s var(--ease), transform .35s var(--ease);
}
.corner svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.corner:hover{color:var(--ink);border-color:var(--edge-lit)}
.corner:active{transform:scale(.94)}
.corner[aria-expanded="true"]{color:var(--lum);border-color:var(--lum-line)}
.corner.c2{right:calc(1.5rem + var(--corner) + var(--corner-gap))}
.corner.c3{right:calc(1.5rem + 2 * (var(--corner) + var(--corner-gap)))}
/* 100%, not 100vw: the fixed rail centres in the viewport without its
   scrollbar, and 100vw counts one, which ate half the gap */
.has-corner .rail{max-width:calc(100% - 2 * (1.5rem + var(--corners) + .75rem))}
/* A narrow desktop (a half-screen window) cannot spare both controls'
   width on each side of a centred rail: the tabs would scroll out of
   sight. There the rail centres in the room left of the pair instead. */
@media (min-width:769px) and (max-width:1100px){
  .two-corners .rail,.three-corners .rail{left:1.5rem;right:calc(1.5rem + var(--corners) + .75rem);max-width:calc(100% - 3rem - var(--corners) - .75rem)}
}

/* ---------------------------------------------------------- sheet
   The menu: a dropdown under the gear on a desktop, a card floating
   above the bar on a phone. Always in the DOM; opacity + pointer-events
   toggle it so it can fade. */
.sheet{
  position:fixed;z-index:70;top:5.1rem;left:0;right:0;bottom:auto;margin:0 auto;
  width:18rem;max-width:calc(100vw - 2rem);max-height:calc(100vh - 6.5rem);overflow-y:auto;
  padding:0;display:block;
  background:var(--sheet-bg);backdrop-filter:blur(28px) saturate(1.6);-webkit-backdrop-filter:blur(28px) saturate(1.6);
  border:1px solid var(--edge);border-radius:1.4rem;box-shadow:0 30px 80px -30px rgba(var(--shadow-rgb),calc(.9 * var(--shadow-k)));
  opacity:0;transform:translateY(-.4rem) scale(.98);pointer-events:none;
  transition:opacity .35s var(--ease), transform .35s var(--ease);
}
.sheet.on{opacity:1;transform:none;pointer-events:auto}
/* Hang the dropdown off the gear where the browser can. The centred
   placement above is the fallback for browsers without anchors. */
@supports (anchor-name:--gear){
  .rail .gear{anchor-name:--gear}
  .sheet{position-anchor:--gear;top:calc(anchor(bottom) + .55rem);left:auto;right:anchor(right);margin:0}
}
.sheet .sheet-in{display:flex;flex-direction:column;padding:.5rem}
.sheet .who{display:flex;align-items:center;gap:.7rem;padding:.7rem .8rem .8rem;border-bottom:1px solid var(--edge-soft);margin:0 0 .3rem;min-width:0}
.sheet .who>div{min-width:0}
.sheet .who .t{font-size:.9rem;font-weight:500;overflow-wrap:anywhere}
.sheet .who .s{font-size:.74rem;color:var(--ink-3);overflow-wrap:anywhere}
.sheet .sheet-grp{display:flex;flex-direction:column;padding:.25rem 0;border-bottom:1px solid var(--edge-soft)}
.sheet .sheet-grp:last-child{border-bottom:0}
/* the rest of the main tabs — only the phone bar runs out of room */
.sheet .sheet-grp.phone-only{display:none}
.sheet .tab{
  display:flex;align-items:center;gap:.7rem;width:100%;min-height:2.6rem;text-align:left;
  padding:.55rem .8rem;border-radius:.9rem;font-size:.88rem;color:var(--ink-2);
  transition:background .3s var(--ease), color .3s var(--ease);
}
.sheet .tab svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:0 0 auto}
.sheet .tab span{min-width:0;overflow:hidden;text-overflow:ellipsis}
.sheet .tab .pip{margin-left:auto;flex:0 0 auto}
.sheet .tab:hover{background:rgba(var(--fg-rgb),.06);color:var(--ink)}
.sheet .tab[aria-selected="true"]{background:rgba(var(--fg-rgb),.07);color:var(--ink)}

/* --------------------------------------------------------- tabbar
   The phone bottom bar. Hidden on a desktop; the phone block below
   shows it. */
.tabbar{display:none}
.bar-b{
  appearance:none;border:0;background:transparent;font:inherit;color:var(--ink-3);cursor:pointer;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.22rem;
  height:var(--bar-h);padding:.35rem .2rem .3rem;
  font-size:10.5px;letter-spacing:.01em;position:relative;min-width:0;
  transition:color .3s var(--ease);
}
.bar-b svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:0 0 auto}
.bar-b span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.bar-b[aria-selected="true"]{color:var(--lum)}
.bar-b .pip{position:absolute;top:.35rem;left:calc(50% + .35rem);margin:0}
.bar-b:active{color:var(--ink)}

/* ----------------------------------------------------------- page */
main{flex:1;width:100%;max-width:78rem;margin:0 auto;padding:8.5rem 1.5rem 7rem;min-width:0;transition:opacity .35s var(--ease)}
.head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:1.5rem;margin-bottom:2.5rem}
.head>*{min-width:0;max-width:100%}
.head .sub{color:var(--ink-3);font-size:.9rem;margin-top:.6rem}
.head .crumb{margin-bottom:1rem;padding:.4rem .9rem .4rem .5rem}
.head .crumb .cap{margin-right:.2rem}
.head-r{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}

/* ----------------------------------------------------- bento grid */
.bento{display:grid;grid-template-columns:repeat(12,1fr);gap:.85rem}
.bento>*{min-width:0}
.c3{grid-column:span 3}.c4{grid-column:span 4}.c5{grid-column:span 5}
.c6{grid-column:span 6}.c7{grid-column:span 7}.c8{grid-column:span 8}.c12{grid-column:span 12}
/* cards on the same bento row share a bottom edge */
.bento>*>.shell:only-child{height:100%}

/* -------------------------------------------------------- metrics */
/* The tile is the query container so the figure scales with the tile
   it sits in, not the viewport: a c3 tile at 1024 is narrow, a c6 is not. */
.metric{display:flex;flex-direction:column;gap:.15rem;justify-content:center;min-height:6.6rem;container-type:inline-size}
.metric .k{font-size:10px;text-transform:uppercase;letter-spacing:.19em;color:var(--ink-3);font-weight:500}
.metric .v{font-size:clamp(1.75rem,16cqi,2.15rem);font-weight:500;letter-spacing:-.045em;line-height:1.05;overflow-wrap:anywhere}
.metric .n{font-size:.78rem;color:var(--ink-4)}
.metric.good .v{color:var(--lum)}
.metric.warn .v{color:var(--warn)}
.metric.crit .v{color:var(--crit)}

/* ---------------------------------------------------------- lists */
.rows{display:flex;flex-direction:column;gap:.3rem;margin-top:1rem;min-width:0}
/* Right column: content-sized, capped at 45% of the row. fit-content()
   resolves against the row, so the cap can never shrink the cell below
   what its own track was sized for (a percentage max-width on the cell
   did exactly that and pushed chips into the title). */
.row{
  display:grid;grid-template-columns:minmax(0,1fr) fit-content(45%);gap:1rem;align-items:center;
  padding:.75rem .9rem;border-radius:1rem;
  background:rgba(var(--fg-rgb),.018);border:1px solid transparent;
  transition:background .5s var(--ease), border-color .5s var(--ease), transform .5s var(--ease);
}
.row>*{min-width:0}
.row:hover{background:rgba(var(--fg-rgb),.045);border-color:var(--edge-soft)}
.row .t{font-size:.9rem;font-weight:450;letter-spacing:-.012em}
.row .s{font-size:.76rem;color:var(--ink-3);margin-top:.12rem}
.row .t,.row .s{overflow-wrap:anywhere}
.row .r{display:flex;flex-direction:column;align-items:flex-end;gap:.2rem;text-align:right;white-space:normal;overflow-wrap:anywhere}
.row .r>*{max-width:100%}
.row .r .mono,.row .r .btn{white-space:nowrap}
.row .r .chip{white-space:normal;text-align:right}
button.row{appearance:none;font:inherit;color:inherit;cursor:pointer;text-align:left;width:100%}
button.row:active{transform:scale(.993)}
.row.msg{display:block}
.row.msg.out{background:var(--lum-dim)}
.row.msg .msg-head{display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.row.msg .body{margin-top:.35rem;color:var(--ink-2);white-space:pre-wrap;word-break:break-word}

.chip{
  display:inline-flex;align-items:center;gap:.35rem;max-width:100%;
  padding:.22rem .58rem;border-radius:999px;
  font-size:10px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;white-space:nowrap;
  background:var(--tray);border:1px solid var(--edge-soft);color:var(--ink-2);
}
.chip.good{background:var(--lum-dim);border-color:var(--lum-line);color:var(--lum)}
.chip.warn{background:var(--warn-dim);border-color:rgba(var(--warn-rgb),.3);color:var(--warn)}
.chip.crit{background:var(--crit-dim);border-color:rgba(var(--crit-rgb),.28);color:var(--crit)}

/* --------------------------------------------------------- button */
.btn{
  appearance:none;cursor:pointer;font:inherit;font-size:.85rem;font-weight:500;
  display:inline-flex;align-items:center;gap:.7rem;max-width:100%;
  padding:.62rem .62rem .62rem 1.15rem;border-radius:999px;
  background:rgba(var(--fg-rgb),.055);border:1px solid var(--edge);color:var(--ink);
  text-decoration:none;
  transition:background .5s var(--ease), border-color .5s var(--ease), transform .35s var(--ease);
}
.btn .cap{
  width:1.85rem;height:1.85rem;border-radius:999px;flex:0 0 auto;
  background:rgba(var(--fg-rgb),.08);display:grid;place-items:center;
  transition:transform .55s var(--ease), background .5s var(--ease);
}
.btn:hover{background:rgba(var(--fg-rgb),.09);border-color:var(--edge-lit)}
.btn:hover .cap{transform:translate(3px,-1px) scale(1.06);background:rgba(var(--fg-rgb),.14)}
.btn:active{transform:scale(.978)}
.btn.primary{background:var(--lum);border-color:transparent;color:var(--on-lum)}
.btn.primary .cap{background:rgba(var(--on-lum-rgb),.14)}
.btn.primary:hover{background:var(--lum-hover)}
.btn.plain{padding:.55rem 1rem;background:transparent}
.btn.plain:hover{background:rgba(var(--fg-rgb),.05)}
.btn.sm{padding:.35rem .75rem;font-size:.78rem}
.btn.danger{color:var(--crit);border-color:rgba(var(--crit-rgb),.28)}
.btn.danger:hover{background:var(--crit-dim)}
.btn[disabled]{opacity:.4;pointer-events:none}
.btn svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round}
.wrap-btns{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center}
.wrap-btns>*{max-width:100%}

/* --------------------------------------------------------- inputs */
.field{
  width:100%;min-width:0;max-width:100%;background:rgba(var(--fg-rgb),.03);border:1px solid var(--edge);
  border-radius:1rem;padding:.8rem 1rem;color:var(--ink);font:inherit;font-size:.88rem;
  transition:border-color .5s var(--ease), background .5s var(--ease);
}
.field:focus{outline:none;border-color:var(--lum-line);background:rgba(var(--fg-rgb),.05)}
.field::placeholder{color:var(--ink-4)}
textarea.field{resize:vertical;min-height:5.5rem;line-height:1.5}
select.field{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
  background-position:calc(100% - 1.15rem) 50%,calc(100% - .8rem) 50%;background-size:.35rem .35rem,.35rem .35rem;background-repeat:no-repeat;padding-right:2.4rem}
select.field option{background:var(--core);color:var(--ink)}
/* a read-only value drawn like a field, so a locked form keeps its rhythm */
.field.ro{background:transparent;border-color:var(--edge-soft);color:var(--ink-2);min-height:2.7rem;display:flex;align-items:center;white-space:pre-wrap;overflow-wrap:anywhere}
label.lab{display:block;font-size:10px;text-transform:uppercase;letter-spacing:.17em;color:var(--ink-3);margin-bottom:.5rem;font-weight:500}
/* one labelled control; a form grid of them */
.f{display:flex;flex-direction:column;gap:0;min-width:0}
.f + .f{margin-top:.8rem}
.fgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(14rem,100%),1fr));gap:.8rem 1rem}
.fgrid>*{min-width:0}
.fgrid .f + .f{margin-top:0}
.fgrid .span{grid-column:1 / -1}

/* read-only marker: a corner label. Rows and cards reserve the corner
   so the label never sits on top of the right-hand column. */
.locked{position:relative}
.locked::after{
  content:'View only';position:absolute;top:.55rem;right:.75rem;pointer-events:none;
  font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-4);white-space:nowrap;
}
.row.locked{padding-top:1.6rem}
.shell.locked::after{top:.95rem;right:1.2rem}
.shell.locked>.core,.core.locked{padding-top:2rem}

/* --------------------------------------------------------- toggle */
.tog{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.7rem 0;border-bottom:1px solid var(--edge-soft)}
.tog:last-child{border-bottom:0}
.tog>*{min-width:0}
.tog .m{font-size:.87rem}
.tog .d{font-size:.75rem;color:var(--ink-3);margin-top:.1rem;max-width:34ch}
.sw{
  appearance:none;width:2.6rem;height:1.5rem;border-radius:999px;flex:0 0 auto;cursor:pointer;
  background:rgba(var(--fg-rgb),.08);border:1px solid var(--edge);position:relative;margin:0;
  transition:background .5s var(--ease), border-color .5s var(--ease);
}
.sw::after{
  content:'';position:absolute;top:2px;left:2px;width:1.1rem;height:1.1rem;border-radius:999px;
  background:var(--ink-2);transition:transform .5s var(--ease), background .5s var(--ease);
}
.sw:checked{background:var(--lum-dim);border-color:var(--lum-line)}
.sw:checked::after{transform:translateX(1.08rem);background:var(--lum)}
.sw[disabled]{opacity:.35;cursor:not-allowed}

/* ---------------------------------------------------- aria-invalid
   A control someone still has to fill in, or one a save was refused over
   (OS.showFormError marks it; What's missing marks every blank one). Red on
   every look: the border and a faint tint on a field or a switch, and the
   words of a tick or a pick group, so it is never a 1px line alone. Typing
   into the control clears it (os.js). background-color, not background, so
   a select keeps its arrow. */
.field[aria-invalid="true"],.field[aria-invalid="true"]:focus,.sw[aria-invalid="true"]{border-color:rgba(var(--crit-rgb),.75);background-color:var(--crit-dim)}
.tog:has(.sw[aria-invalid="true"]) .m,[role="group"][aria-invalid="true"]>label,[role="radiogroup"][aria-invalid="true"] label{color:var(--crit);border-color:rgba(var(--crit-rgb),.45)}

/* --------------------------------------------------------- upload */
/* display:block — the drop zone is a <label>, which is inline by default
   and would draw its dashed border around line fragments, not the box */
.drop{
  display:block;border:1px dashed var(--edge-lit);border-radius:1.25rem;padding:1.6rem;text-align:center;
  background:rgba(var(--fg-rgb),.018);cursor:pointer;
  transition:border-color .5s var(--ease), background .5s var(--ease);
}
.drop:hover,.drop.over{border-color:var(--lum-line);background:var(--lum-dim)}
.drop .h{font-size:.88rem}
.drop .p{font-size:.75rem;color:var(--ink-3);margin-top:.25rem}

/* ---------------------------------------------------------- misc */
.empty{padding:2.5rem 1rem;text-align:center;color:var(--ink-3);font-size:.86rem;overflow-wrap:anywhere}
.divide{height:1px;background:var(--edge-soft);margin:1.4rem 0}
.scrollx{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
.toast{
  position:fixed;left:50%;bottom:2rem;transform:translate(-50%,2rem);z-index:80;max-width:calc(100vw - 2rem);text-align:center;
  background:var(--toast-bg);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  border:1px solid var(--edge-lit);border-radius:999px;padding:.7rem 1.3rem;font-size:.83rem;
  opacity:0;pointer-events:none;transition:opacity .5s var(--ease), transform .5s var(--ease);
}
.toast.on{opacity:1;transform:translate(-50%,0)}
.sub-line{color:var(--ink-3);font-size:.82rem;margin-top:.3rem;line-height:1.5;overflow-wrap:anywhere}
.sub-line.muted,.muted{color:var(--ink-4)}
.h-sm{font-size:.85rem}
.dot-unread{display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--lum);margin-right:.4rem;vertical-align:middle}

/* --------------------------------------------------- scroll reveal */
.rise{opacity:0;transform:translateY(2.2rem);filter:blur(6px)}
.rise.in{opacity:1;transform:none;filter:none;
  transition:opacity .85s var(--ease-out), transform .85s var(--ease-out), filter .85s var(--ease-out)}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition-duration:.01ms!important}
  .rise{opacity:1;transform:none;filter:none}
}

/* the ring follows the element's own radius; forcing one here used to
   re-shape pills and tiles the moment they took keyboard focus */
:focus-visible{outline:2px solid var(--lum-line);outline-offset:3px}

/* ================================================ module primitives
   Shared by the admin, detail and people modules. Each is responsive on
   its own so a module never has to add breakpoints of its own. */

/* a metric tile that drills in */
.shell.tile{display:block;width:100%;transition:border-color .5s var(--ease), transform .35s var(--ease)}
button.shell.tile{appearance:none;font:inherit;color:inherit;text-align:left;cursor:pointer;padding:.375rem}
.shell.tile:hover{border-color:var(--edge-lit)}
button.shell.tile:active{transform:scale(.99)}
.shell.tile .core{height:100%}

/* section title with an optional action on the right */
.sec-head{display:flex;align-items:center;justify-content:space-between;gap:.6rem 1rem;flex-wrap:wrap}
.sec-head>*{min-width:0;max-width:100%}
.sec-head h3{flex:1 1 12rem}

/* a notice across the top of a card or page */
.banner{display:flex;align-items:center;justify-content:space-between;gap:.6rem 1rem;flex-wrap:wrap;padding:.9rem 1.1rem;border-radius:1rem;
  background:var(--warn-dim);border:1px solid rgba(var(--warn-rgb),.3);color:var(--warn);font-size:.85rem;margin-bottom:1rem;overflow-wrap:anywhere}
.banner>*{min-width:0;max-width:100%}
.banner .btn,.banner .wrap-btns{flex:0 0 auto}
.banner.good{background:var(--lum-dim);border-color:var(--lum-line);color:var(--lum)}

/* key / value pairs */
.kv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.35rem 1rem;font-size:.86rem;margin:0}
.kv dt{color:var(--ink-3);min-width:0}
.kv dd{margin:0;min-width:0;overflow-wrap:anywhere}

/* pick-many chips backed by checkboxes. They wrap; a long name breaks
   inside its chip rather than widening the list. */
.tag-list{display:flex;flex-wrap:wrap;gap:.35rem;min-width:0;max-width:100%}
.tag-list label{display:inline-flex;align-items:center;gap:.4rem;min-width:0;max-width:100%;padding:.3rem .7rem;border-radius:999px;border:1px solid var(--edge);font-size:.8rem;cursor:pointer;overflow-wrap:anywhere;
  transition:background .4s var(--ease), border-color .4s var(--ease), color .4s var(--ease)}
.tag-list label:hover{border-color:var(--edge-lit)}
.tag-list label:has(input:checked){background:var(--lum-dim);border-color:var(--lum-line);color:var(--lum)}
.tag-list label:has(input:focus-visible){outline:2px solid var(--lum-line);outline-offset:2px}
.tag-list input{appearance:none;width:0;height:0;margin:0;position:absolute;opacity:0}

/* avatar + name block at the top of a profile */
.avatar.lg{width:3.4rem;height:3.4rem;font-size:1rem}
.profile-head{display:flex;align-items:center;gap:.6rem 1rem;flex-wrap:wrap}
.profile-head>*{min-width:0;max-width:100%}
.profile-head .avatar{flex:0 0 auto}

/* change log: one column, meta line under the summary */
.audit .row{grid-template-columns:minmax(0,1fr);gap:.25rem 1rem}
.audit .row .r{flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-start;gap:.3rem .6rem;text-align:left}

/* ----------------------------------------------------------- fold
   A section minimised until tapped: native <details>. The summary is
   the whole tap target — never under 44px, whatever a module pads it
   to — with the count and the chevron on the right. */
.fold{border:1px solid var(--edge-soft);border-radius:1.1rem;background:rgba(var(--fg-rgb),.018);margin-top:.6rem;min-width:0;max-width:100%}
.fold>summary{
  list-style:none;cursor:pointer;display:flex;align-items:center;gap:.6rem;min-height:2.75rem;padding:.7rem 1rem;
  font-size:.9rem;font-weight:500;letter-spacing:-.012em;user-select:none;-webkit-user-select:none;
  border-radius:inherit;min-width:0;transition:background .4s var(--ease);
}
.fold>summary::-webkit-details-marker{display:none}
.fold>summary::marker{content:''}
.fold>summary:hover{background:rgba(var(--fg-rgb),.03)}
.fold>summary .ft{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.fold>summary .fn{font-size:.76rem;color:var(--ink-3);font-weight:400;min-width:0;overflow-wrap:anywhere;text-align:right}
.fold>summary .chip{flex:0 0 auto}
.fold>summary .fc{display:inline-grid;place-items:center;flex:0 0 auto;width:1.5rem;height:1.5rem;border-radius:999px;background:rgba(var(--fg-rgb),.06);transition:transform .4s var(--ease)}
.fold>summary .fc svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;transform:rotate(-90deg)}
.fold[open]>summary .fc{transform:rotate(90deg)}
.fold[open]>summary{border-bottom:1px solid var(--edge-soft);border-bottom-left-radius:0;border-bottom-right-radius:0}
.fold .fb{padding:.6rem 1rem 1rem;min-width:0;max-width:100%;overflow-wrap:anywhere}
.fold .fb .rows{margin-top:.2rem}

/* ------------------------------------------------------------ seg
   A segmented control. One pill, never taller than its row; when the
   choices outgrow the width it scrolls sideways inside the pill with the
   scrollbar hidden — the row around it never breaks. */
.seg{
  display:inline-flex;gap:.15rem;padding:.2rem;border-radius:999px;vertical-align:middle;
  background:rgba(var(--fg-rgb),.04);border:1px solid var(--edge-soft);
  flex:0 1 auto;min-width:0;max-width:100%;
  overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none;
}
.seg::-webkit-scrollbar{display:none}
.seg-b{
  appearance:none;border:0;background:transparent;font:inherit;font-size:.8rem;color:var(--ink-3);cursor:pointer;
  flex:0 0 auto;min-height:2.1rem;padding:.35rem .85rem;border-radius:999px;white-space:nowrap;
  display:inline-flex;gap:.4rem;align-items:center;justify-content:center;
  transition:background .3s var(--ease), color .3s var(--ease);
}
.seg-b .n{font-size:.7rem;color:var(--ink-4)}
.seg-b:hover{color:var(--ink-2)}
.seg-b[aria-selected="true"]{background:rgba(var(--fg-rgb),.09);color:var(--ink)}
.seg-b[aria-selected="true"] .n{color:var(--ink-3)}

/* ===================================================== responsive */
/* narrow desktops and tablets: the bento halves */
@media (max-width:900px){
  .c3,.c4,.c5,.c6,.c7,.c8{grid-column:span 6}
}

/* phones (and the smallest tablets): one column, a bottom bar, the
   tabs behind it, every tap target 44px */
@media (max-width:768px){
  :root{--r-shell:1.5rem;--r-core:calc(1.5rem - .375rem)}
  h1{font-size:clamp(1.75rem,7.5vw,2.1rem)}
  h2{font-size:1.3rem}

  /* the rail spans the top: brand left, gear right. Tabs live in the bar. */
  .rail{
    top:calc(.75rem + env(safe-area-inset-top));
    left:max(.75rem,env(safe-area-inset-left));right:max(.75rem,env(safe-area-inset-right));
    width:auto;max-width:none;margin:0;justify-content:space-between;padding:.2rem .2rem .2rem .35rem;
  }
  .rail nav{display:none}
  /* the brand link is the rail's only control on the left: as tall as the gear */
  .rail .brand{padding:0 .5rem}
  .rail .brand a{display:flex;align-items:center;min-height:2.75rem}
  .rail .gear{border-left:0;margin-left:0;min-height:2.75rem;min-width:2.75rem;padding:.25rem .3rem .25rem .6rem}
  /* the corner: the phone rail's sum (1px border, .2rem padding, twice,
     around a 2.75rem control), and the rail stops short of it — of both
     controls when there are two */
  :root{--corner:calc(2.75rem + .4rem + 2px)}
  .corner{top:calc(.75rem + env(safe-area-inset-top));right:max(.75rem,env(safe-area-inset-right))}
  .corner.c2{right:calc(max(.75rem,env(safe-area-inset-right)) + var(--corner) + var(--corner-gap))}
  .corner.c3{right:calc(max(.75rem,env(safe-area-inset-right)) + 2 * (var(--corner) + var(--corner-gap)))}
  .has-corner .rail{max-width:none;right:calc(max(.75rem,env(safe-area-inset-right)) + var(--corners) + .5rem)}

  /* the menu floats above the bar; the page behind it steps back */
  .sheet{
    top:auto;left:.75rem;right:.75rem;bottom:calc(var(--bar-h) + .75rem + env(safe-area-inset-bottom));
    width:auto;max-width:none;margin:0;max-height:calc(100dvh - var(--bar-h) - 5.5rem - env(safe-area-inset-bottom));
    transform:translateY(.6rem) scale(.99);
  }
  .sheet.on{transform:none}
  .sheet .sheet-grp.phone-only{display:flex}
  .sheet .tab{min-height:2.85rem;font-size:.95rem;padding:.55rem .85rem}
  .sheet .tab svg{width:18px;height:18px}
  .sheet .who{padding:.75rem .85rem .85rem}
  body.menu-open main{opacity:.45}

  /* the bar: one column per button however many there are, sitting on
     the home indicator */
  .tabbar{
    display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);
    position:fixed;left:0;right:0;bottom:0;z-index:60;
    padding:0 max(.25rem,env(safe-area-inset-right)) env(safe-area-inset-bottom) max(.25rem,env(safe-area-inset-left));
    background:var(--bar-bg);backdrop-filter:blur(28px) saturate(1.6);-webkit-backdrop-filter:blur(28px) saturate(1.6);
    border-top:1px solid var(--edge-soft);
  }

  /* the page clears the rail above and the bar below, and the notch
     either side in landscape */
  main{
    max-width:100%;
    padding:calc(5.6rem + env(safe-area-inset-top)) max(1rem,env(safe-area-inset-right)) calc(var(--bar-h) + 1.75rem + env(safe-area-inset-bottom)) max(1rem,env(safe-area-inset-left));
  }
  /* Measured on a 375px viewport: the bottom padding alone left the last
     card about 44px under the bar, so the page ends with a spacer that
     cannot be swallowed by a grid or a flex row. */
  main::after{content:'';display:block;height:calc(var(--bar-h) + 1rem)}
  .toast{bottom:calc(var(--bar-h) + 1rem + env(safe-area-inset-bottom))}

  /* head: crumb, title, facts, then the actions full width */
  .head{margin-bottom:1.4rem;gap:.9rem 1rem;align-items:flex-start}
  .head .sub{margin-top:.45rem;font-size:.85rem}
  .head .crumb{margin:0 0 .6rem}
  .head-r{width:100%}
  .head-r .btn{flex:1 1 auto;justify-content:space-between}
  .eyebrow{font-size:9px;letter-spacing:.16em;padding:.28rem .6rem}

  .bento{grid-template-columns:1fr;gap:.7rem}
  .c3,.c4,.c5,.c6,.c7,.c8,.c12{grid-column:span 1}
  .core{padding:1.1rem 1rem}
  .core.tight{padding:.95rem 1rem}
  .metric{min-height:5rem}
  .metric .v{font-size:clamp(1.5rem,16cqi,1.75rem)}

  /* rows: the right column sits beside the title while it fits, and
     wraps under it — never squeezed, never clipped — when it does not */
  .row{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem .75rem;padding:.75rem .85rem}
  .row>:first-child{flex:1 1 55%;min-width:0}
  .row>.r{flex:1 1 auto;max-width:100%;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:.3rem .4rem;text-align:right}
  .row>.r .chip{white-space:nowrap}
  .audit .row>*{flex:1 1 100%}
  .audit .row>.r{justify-content:flex-start;text-align:left}

  /* tap targets: 44px (2.75rem), the same as the bar, the sheet rows and a fold's summary */
  .btn.sm{min-height:2.75rem;padding:.4rem .85rem}
  .fold>summary{min-height:2.85rem;padding:.7rem .95rem}
  .seg-b{min-height:2.75rem;padding:.4rem .95rem;font-size:.84rem}
  .tag-list{gap:.4rem}
  .tag-list label{min-height:2.75rem;padding:.35rem .85rem}
  .tog{padding:.8rem 0}
  label.tog{cursor:pointer}
  /* the switch keeps its 1.5rem pill; its hit area grows to 2.75rem so a
     thumb lands on it without the whole row having to be a label */
  .sw::before{content:'';position:absolute;inset:-.65rem -.5rem}

  /* forms stack; 16px stops iOS zooming into a focused field, which is
     itself a way the page ends up wider than the viewport */
  .field{font-size:1rem}
  .fgrid{gap:.8rem}
}
@media (max-width:640px){
  .fgrid{grid-template-columns:1fr}
}
/* the smallest phones: a touch tighter so a row still has room to breathe */
@media (max-width:400px){
  .core{padding:1rem .9rem}
  .row{padding:.7rem .75rem}
  .rail .brand{font-size:.85rem}
}


/* ================================================================ looks
   Four looks, two per mode. The head script on every page resolves the
   person's choice (system / light / dark, plus which look for each) to a
   single data-palette on <html> before the first paint, so there is no
   flash; the Appearance page and a change of device setting re-resolve. */

/* Midnight — the blue-black most people know from GitHub's dark mode,
   with a sky accent instead of mint. Softer than pure black on OLED. */
:root[data-palette="midnight"]{
  color-scheme:dark;
  --void:#0b0f19;
  --core:#121826;
  --fg-rgb:226,232,240;
  --ink:#e6edf3;
  --ink-rgb:230,237,243;
  --lum:#7dd3fc;
  --lum-rgb:125,211,252;
  --lum-hover:#a5e3fd;
  --on-lum:#06202e;
  --on-lum-rgb:6,32,46;
  --acc:#c4b5fd;
  --acc-rgb:167,139,250;
  --warn:#fbbf24;
  --warn-rgb:251,191,36;
  --crit:#fb7185;
  --crit-rgb:251,113,133;
  --rail-bg:rgba(13,18,30,.74);
  --sheet-bg:rgba(15,21,34,.92);
  --bar-bg:rgba(11,15,25,.88);
  --toast-bg:rgba(15,21,34,.92);
}

/* Paper — white-heavy. The glass is tinted with a mid slate rather than
   black so the same alphas read as airy grey, not as smudges. The accent
   is a deep green that passes contrast on white. */
:root[data-palette="paper"]{
  color-scheme:light;
  --void:#ffffff;
  --core:#ffffff;
  --fg-rgb:71,85,105;
  --tray:rgba(var(--fg-rgb),.07);
  --core-hi:rgba(var(--fg-rgb),.10);
  --edge:rgba(var(--fg-rgb),.14);
  --edge-soft:rgba(var(--fg-rgb),.09);
  --edge-lit:rgba(var(--fg-rgb),.26);
  --ink:#0f172a;
  --ink-rgb:15,23,42;
  --ink-2:rgba(var(--ink-rgb),.68);
  --ink-3:rgba(var(--ink-rgb),.48);
  --ink-4:rgba(var(--ink-rgb),.32);
  --lum:#0a7f55;
  --lum-rgb:10,127,85;
  --lum-dim:rgba(var(--lum-rgb),.10);
  --lum-line:rgba(var(--lum-rgb),.35);
  --lum-hover:#0b9663;
  --on-lum:#ffffff;
  --on-lum-rgb:255,255,255;
  --acc:#4f46e5;
  --acc-rgb:99,102,241;
  --warn:#b45309;
  --warn-rgb:180,83,9;
  --warn-dim:rgba(var(--warn-rgb),.10);
  --crit:#dc2626;
  --crit-rgb:220,38,38;
  --crit-dim:rgba(var(--crit-rgb),.08);
  --rail-bg:rgba(255,255,255,.78);
  --sheet-bg:rgba(255,255,255,.94);
  --bar-bg:rgba(255,255,255,.9);
  --toast-bg:rgba(255,255,255,.96);
  --mesh-1:rgba(var(--lum-rgb),.07);
  --mesh-2:rgba(var(--acc-rgb),.06);
  --mesh-3:rgba(var(--lum-rgb),.04);
  --grain:.035;
  --shadow-rgb:15,23,42;
  --shadow-k:.22;
}

/* Linen — cream. Warm stone ink on a warm page, with a cool teal accent
   so the whole thing does not turn beige; cards sit a touch lighter than
   the ground, the editorial way round. */
:root[data-palette="linen"]{
  color-scheme:light;
  --void:#f6f1e7;
  --core:#fdfaf4;
  --fg-rgb:87,83,78;
  --tray:rgba(var(--fg-rgb),.07);
  --core-hi:rgba(var(--fg-rgb),.10);
  --edge:rgba(var(--fg-rgb),.14);
  --edge-soft:rgba(var(--fg-rgb),.09);
  --edge-lit:rgba(var(--fg-rgb),.26);
  --ink:#1c1917;
  --ink-rgb:28,25,23;
  --ink-2:rgba(var(--ink-rgb),.68);
  --ink-3:rgba(var(--ink-rgb),.48);
  --ink-4:rgba(var(--ink-rgb),.32);
  --lum:#0f766e;
  --lum-rgb:15,118,110;
  --lum-dim:rgba(var(--lum-rgb),.10);
  --lum-line:rgba(var(--lum-rgb),.35);
  --lum-hover:#0d8a80;
  --on-lum:#ffffff;
  --on-lum-rgb:255,255,255;
  --acc:#c2410c;
  --acc-rgb:194,65,12;
  --warn:#a16207;
  --warn-rgb:161,98,7;
  --warn-dim:rgba(var(--warn-rgb),.10);
  --crit:#b91c1c;
  --crit-rgb:185,28,28;
  --crit-dim:rgba(var(--crit-rgb),.08);
  --rail-bg:rgba(250,246,238,.8);
  --sheet-bg:rgba(253,250,244,.95);
  --bar-bg:rgba(250,246,238,.9);
  --toast-bg:rgba(253,250,244,.96);
  --mesh-1:rgba(var(--lum-rgb),.07);
  --mesh-2:rgba(var(--acc-rgb),.05);
  --mesh-3:rgba(var(--lum-rgb),.04);
  --grain:.035;
  --shadow-rgb:60,45,30;
  --shadow-k:.22;
}

/* Light looks: the film grain is a dark speckle rather than a light one. */
:root[data-palette="paper"] body::after,
:root[data-palette="linen"] body::after{filter:invert(1)}


/* ------------------------------------------------------ appearance page */
.looks{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));gap:.8rem;margin-top:.4rem}
.look{
  appearance:none;font:inherit;color:inherit;text-align:left;cursor:pointer;
  display:flex;flex-direction:column;gap:.45rem;padding:.5rem;
  background:rgba(var(--fg-rgb),.03);border:1px solid var(--edge-soft);border-radius:1.2rem;
  transition:border-color .4s var(--ease), background .4s var(--ease), transform .3s var(--ease);
}
.look:hover{border-color:var(--edge-lit);background:rgba(var(--fg-rgb),.05)}
.look:active{transform:scale(.985)}
.look.on{border-color:var(--lum-line);box-shadow:0 0 0 3px var(--lum-dim)}
.look-prev{
  display:block;height:5.4rem;border-radius:.9rem;position:relative;overflow:hidden;
  border:1px solid rgba(var(--fg-rgb),.08);
}
.look-prev .lp-card{
  position:absolute;left:12%;right:12%;top:22%;bottom:22%;border-radius:.6rem;
  border:1px solid;display:flex;flex-direction:column;gap:.35rem;padding:.6rem .7rem;
}
.look-prev .lp-card i{display:block;height:.35rem;width:70%;border-radius:999px;opacity:.85}
.look-prev .lp-card b{display:block;width:1.3rem;height:.6rem;border-radius:999px;margin-top:auto}
.look-t{font-size:.9rem;font-weight:500;padding:0 .35rem;display:flex;align-items:center;flex-wrap:wrap;gap:.2rem}
.look-s{font-size:.76rem;color:var(--ink-3);padding:0 .35rem .3rem;line-height:1.4}
@media (max-width:768px){ .looks{grid-template-columns:1fr 1fr} }
@media (max-width:400px){ .looks{grid-template-columns:1fr} }
