::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #3a3c43; border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: #565963; }

* { scrollbar-color: #3a3c43 transparent; }

body { color-scheme: dark; }

.fade-in { animation: fadeIn .25s ease-out; }
/* backwards: so an element given an animation-delay (the feed's post
   stagger) renders at the "from" keyframe during that delay instead of
   flashing fully visible first -- a no-op for every delay:0 use. */
.slide-up { animation: slideUp .3s ease-out backwards; }
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes slideUp { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: translateY(0) } }

/* ---- Loading system -------------------------------------------------------
   One look for every "something is loading" moment: the boot screen, page
   gates, skeleton placeholders, spinners, busy buttons, the thin top bar and
   the AI "generating" shimmer. It is the instrument language at rest: graphite
   surfaces and ONE signal-orange light that moves -- never a field of glow.
   Loops animate transform/opacity wherever possible (compositor-only, cheap
   on a phone); every loop is tamed in the prefers-reduced-motion block that
   closes this section. */

/* A ring with a comet-tail arc. Size comes from width/height (<Spinner> sets
   both, plus --t for the ring thickness); track and arc are one
   conic-gradient, cut into a ring by the mask. */
.sk-spinner {
  --t: 2.5px;
  display: inline-block;
  border-radius: 9999px;
  background:
    conic-gradient(from 0deg, rgba(255,106,31,0) 0deg, rgba(255,106,31,.4) 150deg, #ff6a1f 330deg, #ffc09c 360deg),
    rgba(255,255,255,.09);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--t) - .6px), #000 calc(100% - var(--t)));
  mask: radial-gradient(farthest-side, transparent calc(100% - var(--t) - .6px), #000 calc(100% - var(--t)));
  animation: skSpin .8s linear infinite;
}
@keyframes skSpin { to { transform: rotate(360deg); } }

/* Animated ellipsis for a "Loading…" label: three dots that rise in turn.
   Sized in em so it follows the label's font size. */
.sk-dots { display: inline-flex; gap: .22em; margin-left: .26em; }
.sk-dots i { width: .3em; height: .3em; border-radius: 9999px; background: currentColor; opacity: .3; animation: skDot 1.2s ease-in-out infinite; }
.sk-dots i:nth-child(2) { animation-delay: .16s; }
.sk-dots i:nth-child(3) { animation-delay: .32s; }
@keyframes skDot { 0%, 70%, 100% { opacity: .3; transform: translateY(0); } 35% { opacity: 1; transform: translateY(-.16em); } }

/* A content-shaped placeholder block with a quiet light sweep moving across
   it -- stands in for text/images while real data loads, in the exact size and
   position the real content will occupy (prevents layout shift). Sibling
   blocks start a beat after the one before (a waterfall, not every block
   sweeping in lockstep) and the block itself breathes very slightly. */
.sk-skeleton {
  position: relative;
  overflow: hidden;
  background: var(--sk-inset, #0d0d0f);
  border-radius: 6px;
  animation: skSkeletonPulse 2.2s ease-in-out infinite;
  animation-delay: var(--sk-d, 0s);
}
.sk-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(100deg, transparent 0%, rgba(255,255,255,.03) 32%, rgba(255,255,255,.07) 50%, rgba(255,255,255,.03) 68%, transparent 100%);
  animation: skShimmer 1.7s cubic-bezier(.4, 0, .2, 1) infinite;
  animation-delay: var(--sk-d, 0s);
}
.sk-skeleton:nth-child(2) { --sk-d: .12s; }
.sk-skeleton:nth-child(3) { --sk-d: .24s; }
.sk-skeleton:nth-child(4) { --sk-d: .36s; }
.sk-skeleton:nth-child(5) { --sk-d: .48s; }
.sk-skeleton:nth-child(n+6) { --sk-d: .6s; }
@keyframes skShimmer { 100% { transform: translateX(100%); } }
@keyframes skSkeletonPulse { 0%, 100% { opacity: 1; } 50% { opacity: .72; } }

/* ---- Boot screen -----------------------------------------------------------
   index.html's static pre-boot placeholder and <BootScreen/> (the app's
   full-screen loader) render the SAME markup against these rules, so Preact
   adopts the DOM that is already on screen and the animation just carries on
   -- no visible swap once the app mounts. A device powering on: the mark,
   its LED breathing, the wordmark, a lit bead travelling along an inset slot. */
.sk-boot {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 24px;
  background: #0e0e10;
  color: #ececee;
  text-align: center;
}
/* One overhead light on the matte surface. */
.sk-boot::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse 52% 46% at 50% 36%, rgba(255,255,255,.05) 0%, rgba(255,255,255,.02) 45%, rgba(255,255,255,0) 100%);
}
.sk-boot-stage { position: relative; display: grid; place-items: center; width: 96px; height: 96px; }
.sk-boot-tile {
  position: relative;
  display: block;
  width: 88px;
  height: 88px;
  border-radius: 22.6%;
  box-shadow: 0 22px 40px -18px rgba(0,0,0,.9);
}
.sk-boot-tile img { display: block; width: 100%; height: 100%; }
/* The mark's LED breathes: a soft orange halo laid over the dot (49.3% / 74.7% of the tile). */
.sk-boot-tile::after {
  content: "";
  position: absolute;
  left: 49.3%;
  top: 74.7%;
  width: 54%;
  height: 54%;
  transform: translate(-50%, -50%);
  border-radius: 9999px;
  background: radial-gradient(closest-side, rgba(255,106,31,.7) 0%, rgba(255,106,31,.3) 38%, rgba(255,106,31,.1) 66%, rgba(255,106,31,0) 100%);
  mix-blend-mode: screen;
  will-change: transform, opacity;
  animation: skBootLed 2.1s ease-in-out infinite;
}
@keyframes skBootLed {
  0%, 100% { opacity: .12; transform: translate(-50%, -50%) scale(.78); }
  50% { opacity: 1; transform: translate(-50%, -50%) scale(1.06); }
}
.sk-boot-word {
  margin-top: 28px;
  font-size: 22px;
  font-weight: 650;
  line-height: 1;
  letter-spacing: -.03em;
  color: #f5f5f6;
}
.sk-boot-word b { font-weight: inherit; color: #ff6a1f; }
/* An inset slot with a lit bead travelling along it. */
.sk-boot-track {
  position: relative;
  width: 168px;
  height: 6px;
  margin-top: 24px;
  overflow: hidden;
  border-radius: 9999px;
  background: linear-gradient(180deg, #09090b 0%, #0d0d0f 100%);
  box-shadow: inset 0 1px 3px rgba(0,0,0,.75), inset 0 0 0 1px rgba(0,0,0,.35), 0 1px 0 rgba(255,255,255,.045);
}
.sk-boot-track > span {
  position: absolute;
  top: 1px;
  bottom: 1px;
  left: 1px;
  width: 34%;
  border-radius: 9999px;
  background: linear-gradient(180deg, #ff9560 0%, #ff6a1f 55%, #f0550f 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.45);
  transform: translateX(0);
  animation: skBootBead 1.7s cubic-bezier(.65, 0, .35, 1) infinite alternate;
}
@keyframes skBootBead { to { transform: translateX(190%); } }
.sk-boot-label {
  display: inline-flex;
  align-items: baseline;
  margin-top: 18px;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #868993;
}
/* The label changes with the real boot phase (sign-in check -> workspace);
   a keyed remount replays this so each new phase settles in. */
.sk-boot-phase { animation: skBootPhase .4s var(--sk-ease-out) both; }
@keyframes skBootPhase { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (max-width: 480px) {
  .sk-boot-stage { width: 84px; height: 84px; }
  .sk-boot-tile { width: 76px; height: 76px; }
  .sk-boot-word { margin-top: 24px; font-size: 20px; }
}

/* ---- Page gate (<LoadingState/>): a compact echo of the boot mark -------- */
.sk-orbit { position: relative; display: inline-grid; place-items: center; width: 52px; height: 52px; }
.sk-orbit-ring { --t: 2.5px; position: absolute; inset: 0; }
.sk-orbit > img, .sk-orbit-core { width: 26px; height: 26px; }
.sk-orbit > img { border-radius: 22.6%; box-shadow: 0 6px 12px -6px rgba(0,0,0,.85); }
.sk-orbit-core { border-radius: 9999px; background: radial-gradient(circle, #ff8f55 0 28%, rgba(255,106,31,.35) 46%, rgba(255,106,31,0) 72%); animation: skOrbitBreathe 2.2s ease-in-out infinite; }
@keyframes skOrbitBreathe { 0%, 100% { transform: scale(.88); opacity: .75; } 50% { transform: scale(1.06); opacity: 1; } }

/* ---- Top loading bar -----------------------------------------------------
   <LoadingBar/> (mounted once in the app shell) shows this while any
   placeholder -- skeleton, spinner, page gate -- is on screen. */
.sk-loadbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 90;
  height: 2px;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s var(--sk-ease-standard);
}
.sk-loadbar[data-active="true"] { opacity: 1; }
.sk-loadbar::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 38%;
  background: linear-gradient(90deg, rgba(255,106,31,0), #ff6a1f 45%, #ffb089 88%, #fff);
  transform: translateX(-100%);
  animation: skLoadbar 1.25s cubic-bezier(.65, 0, .35, 1) infinite;
}
.sk-loadbar[data-active="false"]::before { animation-play-state: paused; }
@keyframes skLoadbar { 100% { transform: translateX(290%); } }

/* ---- Busy button: spinner + a soft sheen passing over the face ----------- */
button[data-loading="true"] { position: relative; overflow: hidden; cursor: progress; }
button[data-loading="true"]:disabled { opacity: .88; }
button[data-loading="true"]::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 25%, rgba(255,255,255,.14) 50%, transparent 75%);
  transform: translateX(-100%);
  animation: skShimmer 1.5s cubic-bezier(.4, 0, .2, 1) infinite;
}
/* on the lit (orange) key the arc is dark, like the legend printed on it */
.sk-btn-primary .sk-spinner {
  background: conic-gradient(from 0deg, rgba(29,13,4,0) 0deg, rgba(29,13,4,.5) 200deg, #1d0d04 360deg), rgba(29,13,4,.16);
}
.sk-btn-danger .sk-spinner {
  background: conic-gradient(from 0deg, rgba(255,255,255,0) 0deg, rgba(255,255,255,.55) 200deg, #fff 360deg), rgba(255,255,255,.18);
}

/* ---- "Generating" state for AI output ------------------------------------ */
.sk-ai-orb {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 9999px;
  color: #ff8f55;
  background: rgba(255,106,31,.12);
  animation: skAiPing 1.7s ease-out infinite;
}
.sk-ai-orb svg { animation: skAiTwinkle 1.7s ease-in-out infinite; }
@keyframes skAiPing { 0% { box-shadow: 0 0 0 0 rgba(255,106,31,.4); } 100% { box-shadow: 0 0 0 12px rgba(255,106,31,0); } }
@keyframes skAiTwinkle { 0%, 100% { transform: scale(.88) rotate(0deg); } 50% { transform: scale(1.1) rotate(14deg); } }
/* Text with a light sweep running through it -- "still working on it". */
.sk-shimmer-text {
  color: #a2a5ae;
  background: linear-gradient(100deg, #a2a5ae 35%, #fff 50%, #a2a5ae 65%) 150% 0 / 250% 100% no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: skTextSweep 2.1s linear infinite;
}
@keyframes skTextSweep { to { background-position: -50% 0; } }

/* Reduced motion: nothing slides, floats, spins fast or sweeps. Spinners keep
   turning, slowly -- an indicator that stops reads as a frozen page -- and
   the indeterminate bars become a gentle pulse. */
@media (prefers-reduced-motion: reduce) {
  .sk-spinner { animation-duration: 3s !important; }
  .sk-boot-tile::after, .sk-orbit-core, .sk-ai-orb, .sk-ai-orb svg, .sk-boot-phase { animation: none !important; }
  .sk-boot-tile::after { opacity: .7; transform: translate(-50%, -50%); }
  .sk-boot-track > span, .sk-loadbar::before { width: 100%; transform: none !important; animation: skReducedPulse 1.8s ease-in-out infinite !important; }
  .sk-boot-track > span { left: 1px; right: 1px; width: auto; }
  .sk-skeleton, .sk-skeleton::after, button[data-loading="true"]::after { animation: none !important; }
  .sk-skeleton::after, button[data-loading="true"]::after { display: none; }
  .sk-dots i { animation: none !important; opacity: .6; }
  .sk-shimmer-text { animation: none !important; background: none; -webkit-text-fill-color: currentColor; }
}
@keyframes skReducedPulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* A one-time ring, triggered when a notification arrives live (realtime
   INSERT, not just on open) -- pivoted near the top like a real bell's
   clapper, so it reads as the bell itself reacting rather than a generic
   wiggle. Re-added and removed by shell.js per arrival (the animation
   class itself doesn't repeat; a fresh class toggle is what replays it). */
@keyframes skBellRing {
  0%, 100% { transform: rotate(0deg); }
  10%, 30% { transform: rotate(-14deg); }
  20%, 40% { transform: rotate(14deg); }
  50% { transform: rotate(-8deg); }
  60% { transform: rotate(8deg); }
  70%, 80% { transform: rotate(0deg); }
}
.sk-bell-ring { transform-origin: 50% 15%; animation: skBellRing .6s ease-in-out; }

/* A quick single pop, not a bounce -- for an icon flipping to its "active"
   state (liking/saving a post). Re-added and removed by the component per
   press, same convention as .sk-bell-ring. */
@keyframes skIconPop { 0% { transform: scale(1); } 35% { transform: scale(1.3); } 100% { transform: scale(1); } }
.sk-icon-pop { display: inline-flex; animation: skIconPop .32s var(--sk-ease-spring); }

/* The same single-pop idea, sized for a whole button rather than a small
   icon -- FriendButton replays this on every real status change (Add
   Friend -> Request Sent -> Friends, etc). */
@keyframes skBtnStatePop { 0% { transform: scale(1); } 40% { transform: scale(1.06); } 100% { transform: scale(1); } }
.sk-btn-state-pop { animation: skBtnStatePop .28s var(--sk-ease-spring); }

.stimulus-card { transition: transform .15s ease, box-shadow .15s ease; }
.stimulus-card:hover { transform: translateY(-2px); }

/* ==========================================================================
   INSTRUMENT SYSTEM -- graphite, one signal colour, tactile controls
   A quiet matte surface (plates) with depth reserved for what you touch:
   keys, switches, segmented controls, inputs. One light source (top, a touch
   left): a 1px highlight on every upper edge, a soft shadow underneath.
   One accent -- signal orange -- for the primary action and the "on" state;
   LEDs (green / amber / red / steel) for status. Numbers are set in mono.
   Pure CSS, no raster textures: cheap to paint, sharp at any size.
   The ramp below mirrors tailwind.config.js (graphite / signal).
   ========================================================================== */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("./vendor/fonts/inter-cyrillic-ext.woff2") format("woff2");
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("./vendor/fonts/inter-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("./vendor/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Numbers and key legends: Latin plus the two Cyrillic subsets (Russian / Kazakh letters), so a mono figure
   never falls back to a system monospace mid-word. */
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("./vendor/fonts/jetbrains-mono-cyrillic-ext-500.woff2") format("woff2");
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("./vendor/fonts/jetbrains-mono-cyrillic-500.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("./vendor/fonts/jetbrains-mono-latin-500.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* graphite ramp */
  --g-50: #f5f5f6; --g-100: #ececee; --g-200: #dcdde1; --g-300: #c3c5cb; --g-400: #a2a5ae; --g-500: #868993;
  --g-600: #565963; --g-700: #3a3c43; --g-800: #26282d; --g-900: #18191c; --g-950: #0e0e10;
  --canvas: var(--g-950);
  --rail: #111113;

  /* signal + LEDs */
  --signal: #ff6a1f;
  --signal-hi: #ff8438;
  --signal-lo: #f0550f;
  --signal-ink: #1d0d04;              /* legend colour on a lit key */
  --led-ok: #34d399;
  --led-warn: #fbbf24;
  --led-bad: #fb7185;
  --led-info: #86a5d9;
  --led-off: #565963;

  /* edges */
  --hair: rgba(255,255,255,.06);
  --hair-2: rgba(255,255,255,.11);
  --hi: rgba(255,255,255,.07);
  --hi-strong: rgba(255,255,255,.14);
  --edge: rgba(0,0,0,.6);

  /* materials */
  --plate: linear-gradient(180deg, #1c1d21 0%, #17181b 100%);
  --plate-hover: linear-gradient(180deg, #202125 0%, #1a1b1e 100%);
  --well: linear-gradient(180deg, #09090b 0%, #0d0d0f 100%);
  --key: linear-gradient(180deg, #34363c 0%, #26282d 100%);
  --key-hover: linear-gradient(180deg, #3b3d44 0%, #2b2d33 100%);
  --key-down: linear-gradient(180deg, #212327 0%, #26282d 100%);
  --lit: linear-gradient(180deg, #ff8f55 0%, #ff6a1f 50%, #f65c12 100%);
  --lit-hover: linear-gradient(180deg, #ff9a64 0%, #ff7430 50%, #ff6519 100%);
  --lit-down: linear-gradient(180deg, #ee5812 0%, #f26017 100%);

  --sh-plate: inset 0 1px 0 rgba(255,255,255,.055), 0 1px 2px rgba(0,0,0,.45), 0 14px 30px -18px rgba(0,0,0,.85);
  --sh-plate-sm: inset 0 1px 0 rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4);
  --sh-well: inset 0 1px 3px rgba(0,0,0,.75), inset 0 0 0 1px rgba(0,0,0,.35), 0 1px 0 rgba(255,255,255,.045);
  --sh-key: inset 0 1px 0 rgba(255,255,255,.15), inset 0 -1px 0 rgba(0,0,0,.28), 0 1px 0 rgba(0,0,0,.6), 0 2px 5px -1px rgba(0,0,0,.5);
  --sh-key-down: inset 0 1px 3px rgba(0,0,0,.65), inset 0 0 0 1px rgba(0,0,0,.25), 0 1px 0 rgba(255,255,255,.04);
  --sh-lit: inset 0 1px 0 rgba(255,255,255,.5), inset 0 -1px 0 rgba(130,42,0,.35), 0 1px 0 #6d2606, 0 3px 10px -3px rgba(255,106,31,.4);
  --sh-lit-down: inset 0 2px 4px rgba(110,34,0,.55), 0 1px 0 rgba(255,255,255,.1);

  /* names the chat / feed / builder rules further down still read */
  --sk-raised: var(--plate);
  --sk-raised-hover: var(--plate-hover);
  --sk-raised-active: var(--key-down);
  --sk-inset: var(--well);
  --sk-inset-deep: var(--well);
  --sk-sidebar: var(--rail);
  --sk-topbar: var(--canvas);
  --sk-hi: var(--hi);
  --sk-hi-strong: var(--hi-strong);
  --sk-lo: var(--edge);
  --sk-shadow-raised: var(--sh-plate);
  --sk-shadow-raised-sm: var(--sh-plate-sm);
  --sk-shadow-inset: var(--sh-well);
  --sk-shadow-inset-deep: var(--sh-well);
  --sk-accent: var(--lit);
  --sk-accent-active: var(--lit-down);

  /* Motion tokens -- every animation added for the site-wide motion pass
     reads duration/easing from here, so the feel stays one system instead
     of each component inventing its own timing. */
  --sk-ease-out: cubic-bezier(.16, 1, .3, 1);      /* decelerate: entrances */
  --sk-ease-in: cubic-bezier(.7, 0, .84, 0);        /* accelerate: exits */
  --sk-ease-standard: cubic-bezier(.4, 0, .2, 1);   /* simple hover/color/transform */
  --sk-ease-spring: cubic-bezier(.34, 1.56, .64, 1); /* a little overshoot -- sparingly */
  --sk-dur-fast: 120ms;
  --sk-dur-base: 200ms;
  --sk-dur-slow: 320ms;
  --sk-dur-exit: 150ms;
}

/* ---- Motion: shared overlay / backdrop / reveal primitives ---------------
   Modals, dropdowns, popovers and toasts all mount/unmount through
   useMountTransition() (src/lib/motion.js), which sets a `data-state`
   attribute -- "entering" | "entered" | "exiting" -- on a timer so a
   closing overlay plays an exit transition instead of vanishing the
   instant `open` goes false. Only opacity/transform animate (both are
   compositor-only, no layout/paint cost), which is what keeps this cheap
   with several overlays in flight on a low-powered phone. */

.sk-overlay-anim {
  --sk-overlay-y: 4px;
  opacity: 0;
  transform: scale(.96) translateY(var(--sk-overlay-y));
  transition: opacity var(--sk-dur-base) var(--sk-ease-out), transform var(--sk-dur-base) var(--sk-ease-out);
}
/* Anchored-menu direction: default drifts up into place (menus that open
   upward from a trigger, e.g. bottom-full dropdowns); -down is for a
   popover that opens below its trigger; -center drops the drift entirely
   for a dialog with no single anchor edge to grow from. */
.sk-overlay-anim-down { --sk-overlay-y: -4px; }
.sk-overlay-anim-center { --sk-overlay-y: 0px; }
.sk-overlay-anim[data-state="entered"] {
  opacity: 1;
  transform: scale(1) translateY(0);
}
.sk-overlay-anim[data-state="exiting"] {
  transition-duration: var(--sk-dur-exit);
  transition-timing-function: var(--sk-ease-in);
}

/* A drawer sliding in from the left edge (the mobile sidebar) rather than
   scaling/fading in place -- same data-state contract as .sk-overlay-anim. */
.sk-drawer-anim {
  transform: translateX(-100%);
  transition: transform var(--sk-dur-base) var(--sk-ease-out);
}
.sk-drawer-anim[data-state="entered"] { transform: translateX(0); }
.sk-drawer-anim[data-state="exiting"] {
  transition-duration: var(--sk-dur-exit);
  transition-timing-function: var(--sk-ease-in);
}

/* Inline content expanding in place (a comment thread opening below its
   post) -- fade + a small vertical settle, no scale: it's growing out of
   the row above it, not popping up as its own floating surface. */
.sk-expand-anim {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--sk-dur-base) var(--sk-ease-out), transform var(--sk-dur-base) var(--sk-ease-out);
}
.sk-expand-anim[data-state="entered"] { opacity: 1; transform: translateY(0); }
.sk-expand-anim[data-state="exiting"] {
  transition-duration: var(--sk-dur-exit);
  transition-timing-function: var(--sk-ease-in);
}

.sk-backdrop-anim {
  opacity: 0;
  transition: opacity var(--sk-dur-base) var(--sk-ease-out);
}
.sk-backdrop-anim[data-state="entered"] { opacity: 1; }
.sk-backdrop-anim[data-state="exiting"] {
  transition-duration: var(--sk-dur-exit);
  transition-timing-function: var(--sk-ease-in);
}

/* A toast fades/slides out of the stack on dismiss instead of disappearing
   mid-frame; ToastHost gives a toast this class plus data-state="exiting"
   for its last tick before removing it from the array. */
.sk-toast-anim {
  transition: opacity var(--sk-dur-base) var(--sk-ease-out), transform var(--sk-dur-base) var(--sk-ease-out);
}
.sk-toast-anim[data-state="exiting"] {
  opacity: 0;
  transform: translateX(12px) scale(.97);
  transition-duration: var(--sk-dur-exit);
  transition-timing-function: var(--sk-ease-in);
}

/* Scroll-reveal: useReveal() (src/lib/motion.js) toggles data-visible via
   IntersectionObserver. Never starts hidden until the observer is known to
   be attached, so content can't get stuck invisible. */
.sk-reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--sk-dur-slow) var(--sk-ease-out), transform var(--sk-dur-slow) var(--sk-ease-out);
  will-change: opacity, transform;
}
.sk-reveal[data-visible="true"] {
  opacity: 1;
  transform: translateY(0);
}

/* Page/section swap: the router keys each routed page by its path, so
   Preact remounts the wrapper and this plays again on every navigation. */
@keyframes skPageIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.sk-page-enter { animation: skPageIn var(--sk-dur-slow) var(--sk-ease-out); }

/* Language switch: a quick, elegant dip-and-recover so translated text
   changing reads as an intentional transition instead of a flicker.
   Re-triggered by toggling the class on each locale change (CSS
   animations don't replay on their own) -- the same pattern as the bell. */
@keyframes skLocaleFade { 0% { opacity: 1; } 45% { opacity: .4; } 100% { opacity: 1; } }
.sk-locale-fade { animation: skLocaleFade .36s var(--sk-ease-standard); }

/* ---- Type helpers ------------------------------------------------------------ */

/* Engraved caption: tiny, tracked, uppercase -- section labels, stat labels. */
.sk-caption { font-size: 11px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; color: var(--g-500); }
/* Readouts: mono, tabular, slashed zero. */
.sk-num { font-family: var(--font-mono); font-weight: 500; font-variant-numeric: tabular-nums slashed-zero; letter-spacing: -.02em; }
/* A keycap legend, e.g. the "[" shortcut hint on the sidebar key. */
.sk-kbd {
  display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 5px; font: 500 11px/1 var(--font-mono); color: var(--g-400);
  background: var(--well); border: 1px solid rgba(0,0,0,.6); box-shadow: var(--sh-well);
}

::selection { background: rgba(255,106,31,.35); color: #fff; }
:focus-visible { outline: 2px solid rgba(255,106,31,.7); outline-offset: 2px; }

/* ---- Plates and wells ------------------------------------------------------- */

.sk-panel {
  background: var(--plate);
  border: 1px solid var(--hair);
  border-radius: 14px;
  box-shadow: var(--sh-plate);
}

.sk-panel-flat {
  background: var(--plate);
  border: 1px solid var(--hair);
  box-shadow: var(--sh-plate-sm);
}

.sk-display,
.sk-display-deep {
  background: var(--well);
  border: 1px solid rgba(0,0,0,.6);
  box-shadow: var(--sh-well);
}

/* A standby/power-on light breathing behind an inset display -- used for a
   single focal "press to start" control, never more than one at a time. */
@keyframes skBreathe {
  0%, 100% { box-shadow: var(--sh-well), 0 0 18px 1px rgba(255,106,31,.14); }
  50% { box-shadow: var(--sh-well), 0 0 34px 7px rgba(255,106,31,.3); }
}
.sk-breathe { animation: skBreathe 2.6s ease-in-out infinite; }

/* ---- Stat readouts ------------------------------------------------------------ */

.sk-stat { min-width: 0; padding: 16px 18px; border-radius: 14px; background: var(--plate); border: 1px solid var(--hair); box-shadow: var(--sh-plate-sm); }
.sk-stat-label { font-size: 11px; font-weight: 600; letter-spacing: .09em; line-height: 1.35; text-transform: uppercase; color: var(--g-500); }
.sk-stat-value { margin-top: 10px; font: 500 28px/1.1 var(--font-mono); font-variant-numeric: tabular-nums slashed-zero; letter-spacing: -.03em; color: var(--g-50); }
.sk-stat-hint { margin-top: 8px; font-size: 12px; line-height: 1.4; color: var(--g-500); }
/* a unit inside a readout: small, in the text face, a little air on both sides */
.sk-unit { margin: 0 .5em 0 .22em; font: 500 .48em/1 Inter, system-ui, sans-serif; letter-spacing: .01em; color: var(--g-400); }
.sk-unit:last-child { margin-right: 0; }
/* A row of readouts on ONE plate, separated by hairlines (instead of four boxes). */
.sk-stat-strip {
  display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
  overflow: hidden; border-radius: 14px; background: var(--plate); border: 1px solid var(--hair); box-shadow: var(--sh-plate);
}
/* the same strip sunk into a card as a display window (report preview) */
.sk-stat-strip-well { background: var(--well); border-color: rgba(0,0,0,.6); box-shadow: var(--sh-well); }
.sk-stat-strip > .sk-stat { border: 0; border-radius: 0; background: none; box-shadow: none; }
.sk-stat-strip > .sk-stat + .sk-stat { border-left: 1px solid var(--hair); }
@media (max-width: 1023px) {
  .sk-stat-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sk-stat-strip > .sk-stat:nth-child(odd) { border-left: 0; }
  .sk-stat-strip > .sk-stat:nth-child(n+3) { border-top: 1px solid var(--hair); }
  /* an odd last tile (a strip of three) takes the whole row */
  .sk-stat-strip > .sk-stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ---- Donut readout + legend ----------------------------------------------------------- */

.sk-donut-ring { position: relative; }
.sk-donut-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; pointer-events: none; }
.sk-donut-value { font-size: 30px; line-height: 1; color: var(--g-50); }
.sk-legend { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 18px; margin: 18px 0 0; padding: 0; list-style: none; }
.sk-legend li { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 12px; color: var(--g-400); }
.sk-legend i { flex: none; width: 7px; height: 7px; border-radius: 50%; }
.sk-legend span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk-legend b { flex: none; font-size: 12px; color: var(--g-200); }

/* ---- Keys (buttons) --------------------------------------------------------------- */

.sk-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--g-100);
  background: var(--key);
  border: 1px solid var(--edge);
  box-shadow: var(--sh-key);
  text-shadow: 0 1px 0 rgba(0,0,0,.45);
  transition: transform var(--sk-dur-fast) var(--sk-ease-standard), box-shadow var(--sk-dur-fast) var(--sk-ease-standard), background var(--sk-dur-base) var(--sk-ease-standard), color var(--sk-dur-fast);
}
.sk-btn:hover:not(:disabled) { background: var(--key-hover); color: #fff; }
.sk-btn:active:not(:disabled),
.sk-btn[data-pressed="true"] {
  background: var(--key-down);
  box-shadow: var(--sh-key-down);
  transform: translateY(1px);
}
.sk-btn:disabled { opacity: .45; cursor: not-allowed; }

/* The lit key: dark legend on signal orange, like the record button on a piece of hardware. */
.sk-btn-primary {
  background: var(--lit);
  border: 1px solid #a53b0a;
  box-shadow: var(--sh-lit);
  color: var(--signal-ink);
  font-weight: 600;
  text-shadow: 0 1px 0 rgba(255,255,255,.3);
}
.sk-btn-primary:hover:not(:disabled) { background: var(--lit-hover); color: var(--signal-ink); }
.sk-btn-primary:active:not(:disabled) {
  background: var(--lit-down);
  box-shadow: var(--sh-lit-down);
  transform: translateY(1px);
}

.sk-btn-danger {
  color: #fff;
  background: linear-gradient(180deg, #f2677a 0%, #e5484d 55%, #d23a43 100%);
  border: 1px solid #8c1d24;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), inset 0 -1px 0 rgba(90,10,18,.35), 0 1px 0 #5c0f15, 0 3px 10px -3px rgba(229,72,77,.4);
  text-shadow: 0 1px 0 rgba(0,0,0,.25);
}
.sk-btn-danger:hover:not(:disabled) { background: linear-gradient(180deg, #f5788a 0%, #ea545a 55%, #d8444c 100%); color: #fff; }
.sk-btn-danger:active:not(:disabled) { background: linear-gradient(180deg, #d23a43 0%, #dc4047 100%); box-shadow: inset 0 2px 4px rgba(90,10,18,.55); transform: translateY(1px); }

/* A key that is not available right now is simply not lit: matte graphite, legend dimmed. */
.sk-btn-primary:disabled:not([data-loading="true"]),
.sk-btn-danger:disabled:not([data-loading="true"]) {
  opacity: 1;
  color: var(--g-500);
  background: linear-gradient(180deg, #2c2e33 0%, #26282c 100%);
  border-color: var(--edge);
  box-shadow: var(--sh-key);
  text-shadow: none;
}

/* A stronger presence for a single hero CTA -- not for routine buttons. */
.sk-btn-hero { box-shadow: var(--sh-lit), 0 8px 26px -6px rgba(255,106,31,.5); }
.sk-btn-hero:hover:not(:disabled) { box-shadow: var(--sh-lit), 0 10px 30px -6px rgba(255,106,31,.65); }

/* ---- Inputs (wells) ------------------------------------------------------------------ */

/* full width unless a utility (w-auto, w-36...) says otherwise: :where() keeps this at zero specificity */
:where(.sk-input) { width: 100%; }
.sk-input {
  color: var(--g-100);
  background: var(--well);
  border: 1px solid rgba(0,0,0,.65);
  box-shadow: var(--sh-well);
  transition: box-shadow var(--sk-dur-fast) var(--sk-ease-standard), border-color var(--sk-dur-fast) var(--sk-ease-standard);
}
.sk-input:hover:not(:disabled):not(:focus) { box-shadow: var(--sh-well), 0 0 0 1px rgba(255,255,255,.05); }
.sk-input:focus {
  outline: none;
  border-color: rgba(255,106,31,.75);
  box-shadow: var(--sh-well), 0 0 0 3px rgba(255,106,31,.18);
}

/* Select: our own chevron, same well as the text inputs. */
select.sk-input {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding-right: 34px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23868993' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E") no-repeat right 12px center / 12px 12px,
    var(--well);
}
select.sk-input:disabled { cursor: not-allowed; }

/* The closed <select> inherits sk-input's light text color, but its open
   OPTION LIST is rendered by the browser/OS chrome, which ignores most CSS
   on the select itself -- background defaults to the browser's own (often
   near-white), leaving the inherited light text nearly unreadable on it.
   background-color/color on <option> are the two properties that actually
   apply cross-browser, unlike the select's own gradient/shadow. */
select.sk-input option {
  background-color: #1a1b1e;
  color: #ececee;
}
select.sk-input option:checked {
  background-color: #7e2f10;
  color: #fff;
}

/* ---- Icons: heavy strokes with a tinted body ("duotone"), see components/icons.js ------------------- */
.ic { flex: none; }
.ic .b, .ic .t { fill: currentColor; fill-opacity: .2; }
.ic .t { stroke: none; }
.ic .f { fill: currentColor; stroke: none; }
.ic[data-filled="true"] .b, .ic[data-filled="true"] .t { fill-opacity: 1; }
/* the page you are on: the glyph lights up like the LED next to it */
.sk-nav-item[data-active="true"] .ic { filter: drop-shadow(0 0 5px rgba(255,106,31,.55)); }
.sk-nav-item[data-active="true"] .ic .b, .sk-nav-item[data-active="true"] .ic .t { fill-opacity: .3; }

/* ---- Segmented control ------------------------------------------------------------------ */
/* A well holding flat labels; the active one is a raised key with its LED lit. */

.sk-tabs {
  background: var(--well);
  border: 1px solid rgba(0,0,0,.65);
  border-radius: 11px;
  box-shadow: var(--sh-well);
}
.sk-tab {
  color: var(--g-400);
  transition: transform var(--sk-dur-fast) var(--sk-ease-standard), box-shadow var(--sk-dur-fast) var(--sk-ease-standard), background var(--sk-dur-base) var(--sk-ease-standard), color var(--sk-dur-fast);
}
.sk-tab[data-active="true"] {
  color: var(--g-50);
  background: var(--key);
  box-shadow: var(--sh-key), 0 0 0 1px var(--edge);
}
.sk-tab[data-active="true"]::before {
  content: "";
  display: inline-block;
  width: 5px; height: 5px; margin: -1px 8px 0 -2px;
  vertical-align: middle;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 6px 1px rgba(255,106,31,.7);
}
.sk-tab[data-active="false"]:hover { color: var(--g-100); background: rgba(255,255,255,.04); }

/* The sliding key (lib/thumb.js): one raised key glides under the labels; the active label itself is flat while the key is placed. */
.sk-tabs, .sk-thumbhost { position: relative; }
.sk-tabs > button, .sk-thumbhost button { position: relative; z-index: 1; }
.sk-thumb {
  position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 0; pointer-events: none;
  border-radius: 8px;
  background: var(--key);
  box-shadow: var(--sh-key), 0 0 0 1px var(--edge);
  opacity: 0; will-change: transform, width;
}
[data-thumb="on"] > .sk-thumb { opacity: 1; }
[data-thumb="on"] .sk-tab[data-active="true"] { background: transparent; box-shadow: none; }
[data-thumb="on"] .sk-tab[data-active="false"]:hover { background: rgba(255,255,255,.04); }
@media (prefers-reduced-motion: reduce) { .sk-thumb { will-change: auto; } }
/* a short toggle (the language switch) is just the raised key -- no LED on it */
[data-compact="true"] .sk-tab[data-active="true"]::before { display: none; }

/* ---- Switch ---------------------------------------------------------------------------- */

.sk-switch-track {
  background: var(--well);
  border: 1px solid rgba(0,0,0,.65);
  box-shadow: var(--sh-well);
  transition: background var(--sk-dur-base) var(--sk-ease-standard), box-shadow var(--sk-dur-base) var(--sk-ease-standard);
}
.sk-switch-track[data-on="true"] {
  background: linear-gradient(180deg, #8a3109 0%, #d4490e 100%);
  box-shadow: inset 0 1px 3px rgba(50,12,0,.8), inset 0 0 0 1px rgba(50,12,0,.35), 0 0 12px -2px rgba(255,106,31,.35);
}
.sk-switch-knob {
  background: linear-gradient(180deg, #f1f2f4 0%, #b9bcc3 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 1px 3px rgba(0,0,0,.6), 0 0 0 1px rgba(0,0,0,.4);
  transition: transform var(--sk-dur-base) var(--sk-ease-spring);
}

/* ---- Sidebar / topbar / nav ---------------------------------------------------------------- */

.sk-sidebar { background: var(--rail); border-right: 1px solid var(--hair); box-shadow: inset -1px 0 0 rgba(0,0,0,.5); }
.sk-topbar { background: var(--canvas); border-bottom: 1px solid var(--hair); }

.sk-nav-item {
  color: var(--g-400);
  transition: background var(--sk-dur-fast) var(--sk-ease-standard), box-shadow var(--sk-dur-fast) var(--sk-ease-standard), color var(--sk-dur-fast) var(--sk-ease-standard);
}
/* The page you are on is a key that is held down, with a lit strip on its edge. */
.sk-nav-item[data-active="true"] {
  color: var(--g-50);
  background: var(--well);
  box-shadow: var(--sh-well);
}
.sk-nav-item[data-active="true"]::before {
  content: "";
  position: absolute; left: 0; top: 9px; bottom: 9px; width: 2px;
  border-radius: 0 2px 2px 0;
  background: var(--signal);
  box-shadow: 0 0 8px 1px rgba(255,106,31,.6);
}
.sk-nav-item[data-active="false"]:hover { background: rgba(255,255,255,.1); color: var(--g-50); }

/* The collapse / expand key at the foot of the sidebar. */
.sk-collapse {
  display: flex; align-items: center; gap: 10px; width: 100%; height: 34px; padding: 0 8px 0 10px;
  border-radius: 9px; font-size: 13px; font-weight: 500; color: var(--g-300);
  background: var(--key); border: 1px solid var(--edge); box-shadow: var(--sh-key); text-shadow: 0 1px 0 rgba(0,0,0,.45);
  transition: transform var(--sk-dur-fast) var(--sk-ease-standard), box-shadow var(--sk-dur-fast) var(--sk-ease-standard), background var(--sk-dur-base) var(--sk-ease-standard), color var(--sk-dur-fast);
}
.sk-collapse:hover { background: var(--key-hover); color: #fff; }
.sk-collapse:active { background: var(--key-down); box-shadow: var(--sh-key-down); transform: translateY(1px); }
.sk-collapse .sk-kbd { margin-left: auto; }
.sk-collapse[data-rail="true"] { width: 40px; padding: 0; justify-content: center; }
/* the chevrons slide a hair toward the direction they will move the rail */
.sk-collapse svg { transition: transform var(--sk-dur-base) var(--sk-ease-out); }
.sk-collapse:hover svg { transform: translateX(-1.5px); }
.sk-collapse[data-rail="true"]:hover svg { transform: translateX(1.5px); }

/* Unread / request counters: a small lit pill with a mono number. */
.sk-count {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; font: 500 11px/1 var(--font-mono); color: var(--signal-ink);
  background: var(--lit); box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 1px 0 rgba(0,0,0,.4);
}

/* A small key tile carrying one glyph (section icons in cards). */
.sk-tile {
  display: flex; align-items: center; justify-content: center; flex: none; width: 28px; height: 28px; border-radius: 8px;
  color: var(--signal-hi); background: var(--key); border: 1px solid var(--edge); box-shadow: var(--sh-key);
}

/* Initials medallion (no photo): a small graphite disc with a 1px light edge. */
.sk-avatar {
  color: var(--g-100); letter-spacing: .02em;
  background: linear-gradient(180deg, #3c3e45 0%, #2a2c31 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 0 0 1px rgba(0,0,0,.6), 0 1px 3px rgba(0,0,0,.5);
}

/* ---- Status LED badge ------------------------------------------------------------------------- */

.sk-badge {
  display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px 2px 8px; border-radius: 999px;
  font-size: 12px; font-weight: 500; line-height: 18px; white-space: nowrap; color: var(--g-200);
  background: rgba(0,0,0,.32); border: 1px solid var(--hair); box-shadow: inset 0 1px 2px rgba(0,0,0,.45);
}
.sk-badge[data-tone="emerald"] { --led: #34d399; --led-glow: rgba(52,211,153,.65); }
.sk-badge[data-tone="amber"] { --led: #fbbf24; --led-glow: rgba(251,191,36,.6); }
.sk-badge[data-tone="rose"] { --led: #fb7185; --led-glow: rgba(251,113,133,.6); }
.sk-badge[data-tone="teal"] { --led: #2dd4bf; --led-glow: rgba(45,212,191,.55); }
.sk-badge[data-tone="steel"] { --led: #86a5d9; --led-glow: rgba(134,165,217,.55); }
.sk-badge[data-tone="signal"] { --led: #ff6a1f; --led-glow: rgba(255,106,31,.65); }
.sk-led {
  width: 6px; height: 6px; flex-shrink: 0; border-radius: 50%;
  background: var(--led, #565963); box-shadow: 0 0 6px 0 var(--led-glow, transparent);
}

/* ---- Modal / menus ---------------------------------------------------------------------------------- */

.sk-modal {
  background: var(--plate);
  border: 1px solid var(--hair-2);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 1px 2px rgba(0,0,0,.5), 0 30px 70px -20px rgba(0,0,0,.85);
}

/* ---- Variant / spec slot (A/B/C/D) ---------------------------------------------------------------------- */

.sk-slot {
  background: var(--plate);
  border: 1px solid var(--hair);
  box-shadow: var(--sh-plate-sm);
  transition: transform var(--sk-dur-fast) var(--sk-ease-standard), box-shadow var(--sk-dur-fast) var(--sk-ease-standard), background var(--sk-dur-fast) var(--sk-ease-standard), border-color var(--sk-dur-fast);
}
.sk-slot:hover { background: var(--plate-hover); border-color: var(--hair-2); }
.sk-slot[data-selected="true"] {
  border-color: rgba(255,106,31,.7);
  box-shadow: var(--sh-plate-sm), 0 0 0 1px rgba(255,106,31,.3);
}
/* Suggested measurement chips (builder step 4). */
.sk-slot.sk-suggested { border-color: rgba(251,191,36,.5); box-shadow: var(--sh-plate-sm), 0 0 0 1px rgba(251,191,36,.28); }
.sk-slot.sk-suggested:hover { box-shadow: var(--sh-plate-sm), 0 0 0 1px rgba(251,191,36,.5); }
.sk-suggest-hint { color: rgba(251,191,36,.9); }
.sk-suggest-badge { font-size: 10px; line-height: 1; color: #fbbf24; }
.sk-slot-label {
  color: var(--g-100);
  background: var(--key);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 1px 0 rgba(0,0,0,.5);
}

/* ---- Checkbox ----------------------------------------------------------------------------------------------- */

.sk-checkbox {
  appearance: none;
  -webkit-appearance: none;
  background: var(--well);
  box-shadow: var(--sh-well);
  border: 1px solid rgba(0,0,0,.65);
  position: relative;
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--sk-dur-fast) var(--sk-ease-standard), box-shadow var(--sk-dur-fast) var(--sk-ease-standard), border-color var(--sk-dur-fast);
}
.sk-checkbox:checked {
  border-color: rgba(255,106,31,.55);
  box-shadow: var(--sh-well), 0 0 10px -2px rgba(255,106,31,.35);
}
.sk-checkbox:checked::after {
  content: "";
  position: absolute;
  left: 4px; top: 1px;
  width: 4px; height: 8px;
  border: solid var(--signal-hi);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  filter: drop-shadow(0 0 3px rgba(255,106,31,.7));
  animation: skCheckPop .18s var(--sk-ease-spring);
}
@keyframes skCheckPop { from { transform: rotate(45deg) scale(0); } to { transform: rotate(45deg) scale(1); } }
.sk-checkbox:focus-visible { outline: 2px solid rgba(255,106,31,.7); outline-offset: 1px; }

@media (prefers-reduced-motion: reduce) {
  .sk-btn, .sk-slot, .sk-switch-knob, .sk-tab, .sk-checkbox, .sk-input, .sk-switch-track, .sk-nav-item, .sk-progress-fill { transition: none !important; }
  .sk-btn:hover:not(:disabled) { transform: none !important; }
  .sk-checkbox:checked::after { animation: none !important; }
  .sk-bell-ring, .sk-icon-pop, .sk-btn-state-pop { animation: none !important; }

  .sk-overlay-anim, .sk-backdrop-anim, .sk-toast-anim, .sk-drawer-anim, .sk-expand-anim { transition: none !important; }
  .sk-reveal { transition: none !important; opacity: 1 !important; transform: none !important; }
  .sk-page-enter, .sk-locale-fade, .fade-in, .slide-up { animation: none !important; }
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ==========================================================================
   Live badge (Results) + messenger (pages/Messages.js)
   Plain CSS on purpose: vendor/tailwind.css is prebuilt, so brand-new
   utility classes would not exist until the next Tailwind build.
   ========================================================================== */

.sk-live-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: #6ee7b7; background: rgba(16,185,129,.12); border: 1px solid rgba(16,185,129,.3);
}
.sk-live-dot {
  width: 7px; height: 7px; border-radius: 50%; background: #34d399;
  animation: skLivePulse 1.6s ease-out infinite;
}
@keyframes skLivePulse {
  0% { box-shadow: 0 0 0 0 rgba(52,211,153,.55); }
  70% { box-shadow: 0 0 0 7px rgba(52,211,153,0); }
  100% { box-shadow: 0 0 0 0 rgba(52,211,153,0); }
}

.sk-chat {
  display: grid; grid-template-columns: 340px minmax(0, 1fr);
  /* svh, not dvh: svh is pinned to the browser's smallest possible viewport
     (chrome fully shown), so this can never end up taller than what's
     actually visible. dvh tracks the chrome live as it hides/shows on
     scroll -- on mobile that can leave this panel briefly sized for a
     bigger viewport than is currently on screen, pushing the whole page
     into an unwanted scroll that clips this panel's own header behind the
     app's topbar (see the max-width: 767px rule below, where this matters
     far more than here). */
  height: calc(100svh - 11rem); min-height: 440px;
  border-radius: 14px; overflow: hidden; padding: 0;
}
.sk-chat-list { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid rgba(0,0,0,.45); }
.sk-chat-list-head { padding: 16px 16px 10px; }
.sk-chat-list-head h2 { font-size: 18px; font-weight: 600; color: #ececee; margin: 0 0 10px; }
.sk-chat-search { width: 100%; border-radius: 10px; padding: 8px 12px; font-size: 14px; color: #dcdde1; }
.sk-chat-items { flex: 1; overflow-y: auto; padding: 4px 8px 12px; }

.sk-chat-item {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 10px; border-radius: 12px; background: transparent; border: 0; color: inherit; cursor: pointer;
  transition: background var(--sk-dur-fast) var(--sk-ease-standard);
}
.sk-chat-item:hover { background: rgba(255,255,255,.04); }
.sk-chat-item.active { background: var(--well); box-shadow: var(--sh-well); }
/* the avatar is its own button (opens the profile) laid over the row's reserved slot */
.sk-chat-row { position: relative; }
.sk-chat-row:hover > .sk-chat-item:not(.active) { background: rgba(255,255,255,.04); }
.sk-chat-item-slot { flex: 0 0 44px; width: 44px; height: 44px; }
.sk-chat-avatar-hit {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  padding: 0; margin: 0; border: 0; border-radius: 50%; background: none; color: inherit; line-height: 0; cursor: pointer;
  transition: filter var(--sk-dur-fast), transform var(--sk-dur-fast) var(--sk-ease-standard);
}
.sk-chat-avatar-hit:hover { filter: brightness(1.18); }
.sk-chat-avatar-hit:active { transform: translateY(-50%) scale(.96); }
.sk-chat-item-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sk-chat-item-top, .sk-chat-item-bottom { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
.sk-chat-name { font-size: 14px; font-weight: 500; color: #dcdde1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk-chat-name.unread { font-weight: 700; color: #fff; }
.sk-chat-time { font-size: 11px; color: #868993; flex-shrink: 0; }
.sk-chat-preview { font-size: 13px; color: #868993; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk-chat-preview.unread { color: #c3c5cb; }
.sk-chat-unread {
  flex-shrink: 0; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #fff; background: #ff6a1f;
}
.sk-chat-typing-text { color: #34d399; font-style: italic; }
.sk-chat-hint { padding: 18px 14px; font-size: 13px; color: #868993; text-align: center; }

.sk-avatar-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.sk-online-dot {
  position: absolute; right: -1px; bottom: -1px; width: 12px; height: 12px; border-radius: 50%;
  background: #22c55e; border: 2px solid #18191c;
}

.sk-chat-pane { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: rgba(0,0,0,.14); }
.sk-chat-empty { align-items: center; justify-content: center; text-align: center; padding: 24px; }
.sk-chat-head {
  display: flex; align-items: center; gap: 12px; padding: 10px 16px;
  border-bottom: 1px solid rgba(0,0,0,.45); background: rgba(255,255,255,.02);
}
.sk-chat-head-text { min-width: 0; }
.sk-chat-head-name { font-size: 15px; font-weight: 600; color: #ececee; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk-chat-head-status { font-size: 12px; }
.sk-status-online { color: #34d399; }
.sk-status-offline { color: #868993; }
.sk-chat-back {
  display: none; align-items: center; justify-content: center; width: 36px; height: 36px; margin-left: -6px;
  border: 0; border-radius: 10px; background: transparent; color: #c3c5cb; cursor: pointer;
}

.sk-chat-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 3px; overscroll-behavior: contain; }
.sk-chat-skeleton { display: flex; flex-direction: column; gap: 10px; }
.sk-chat-older { display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 12px; color: #868993; padding: 4px 0 8px; }
.sk-chat-day { display: flex; justify-content: center; margin: 12px 0 6px; }
.sk-chat-day span { font-size: 11px; color: #a2a5ae; background: rgba(255,255,255,.06); padding: 3px 12px; border-radius: 999px; }

.sk-msg-row { display: flex; flex-direction: column; align-items: flex-start; }
.sk-msg-row.mine { align-items: flex-end; }
.sk-bubble {
  max-width: min(520px, 78%); padding: 7px 11px 6px; border-radius: 16px 16px 16px 5px;
  background: linear-gradient(180deg, #24262a 0%, #1f2024 100%); box-shadow: inset 0 0 0 1px var(--hair), inset 0 1px 0 rgba(255,255,255,.05);
  color: var(--g-200); font-size: 14.5px; line-height: 1.4;
  overflow-wrap: anywhere; animation: skBubbleIn .18s var(--sk-ease-out) backwards;
}
/* my messages: a raised graphite key, not a coloured balloon -- the signal colour is kept for "read" */
.sk-bubble.mine { border-radius: 16px 16px 5px 16px; background: linear-gradient(180deg, #3d4048 0%, #30333a 100%); box-shadow: inset 0 0 0 1px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.12), 0 1px 0 rgba(0,0,0,.45); color: var(--g-50); }
.sk-bubble.failed { background: rgba(244,63,94,.28); }
.sk-bubble-text { white-space: pre-wrap; }
.sk-bubble-meta { display: inline-flex; align-items: center; gap: 3px; float: right; margin: 6px 0 0 10px; font-size: 10.5px; opacity: .75; line-height: 1; }
.sk-bubble::after { content: ""; display: block; clear: both; }
.sk-tick { display: inline-flex; align-items: center; }
.sk-tick-read { color: var(--signal-hi); opacity: 1; }
.sk-bubble-typing { padding: 11px 14px; }
.sk-msg-retry { margin-top: 3px; border: 0; background: transparent; color: #fb7185; font-size: 12px; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
@keyframes skBubbleIn { from { opacity: 0; transform: translateY(6px) scale(.98); } to { opacity: 1; transform: none; } }

.sk-typing-dots { display: inline-flex; gap: 3px; align-items: center; vertical-align: middle; }
.sk-typing-dots i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .5; animation: skTyping 1.2s infinite ease-in-out; }
.sk-typing-dots i:nth-child(2) { animation-delay: .15s; }
.sk-typing-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes skTyping { 0%, 60%, 100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-3px); opacity: 1; } }

.sk-chat-composer {
  position: relative; display: flex; align-items: flex-end; gap: 8px;
  padding: 10px 12px; border-top: 1px solid rgba(0,0,0,.45); background: rgba(255,255,255,.02);
}
.sk-chat-input { flex: 1; resize: none; border-radius: 18px; padding: 9px 14px; font-size: 14.5px; line-height: 1.35; max-height: 140px; color: #ececee; }
.sk-chat-iconbtn, .sk-chat-send {
  flex-shrink: 0; width: 40px; height: 40px; border-radius: 50%; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.sk-chat-iconbtn { background: transparent; color: #a2a5ae; }
.sk-chat-iconbtn:hover { color: #dcdde1; background: rgba(255,255,255,.06); }
.sk-chat-send { background: var(--lit); color: var(--signal-ink); box-shadow: var(--sh-lit); transition: transform var(--sk-dur-fast) var(--sk-ease-standard), box-shadow var(--sk-dur-fast), background var(--sk-dur-base); }
.sk-chat-send:hover:not(:disabled) { background: var(--lit-hover); }
.sk-chat-send:active:not(:disabled) { background: var(--lit-down); box-shadow: var(--sh-lit-down); transform: translateY(1px); }
/* not available = not lit */
.sk-chat-send:disabled { cursor: default; color: var(--g-500); background: linear-gradient(180deg, #2c2e33 0%, #26282c 100%); box-shadow: var(--sh-key); }
.sk-chat-locked { padding: 14px 16px; text-align: center; font-size: 13px; color: #a2a5ae; border-top: 1px solid rgba(0,0,0,.45); }
.sk-emoji-panel {
  position: absolute; left: 12px; bottom: 58px; z-index: 5; width: 264px; padding: 8px;
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
  background: #1c1d21; border: 1px solid rgba(255,255,255,.08); border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.5);
}
.sk-emoji-panel button { border: 0; background: transparent; font-size: 20px; padding: 4px 0; border-radius: 8px; cursor: pointer; }
.sk-emoji-panel button:hover { background: rgba(255,255,255,.08); }

@media (max-width: 767px) {
  /* Measured on the real mobile Shell layout: topbar ~63px + main's own
     top/bottom padding ~24px each = ~111px (~7rem). 7.5rem leaves a small,
     deliberate margin rather than cutting it exactly there -- and svh (not
     dvh) means that margin can only ever leave a little unused space at
     the bottom, never overflow into a page-level scroll. The previous
     9.5rem was never measured against the actual layout and, combined
     with dvh's live resize as the phone's address bar hides/shows while
     scrolling, could leave this panel taller than the real, current
     viewport -- the page then had to scroll to show all of it, clipping
     this panel's own header behind the app's topbar. */
  .sk-chat { grid-template-columns: minmax(0, 1fr); height: calc(100svh - 7.5rem); }
  .sk-chat[data-pane="chat"] .sk-chat-list { display: none; }
  .sk-chat[data-pane="list"] .sk-chat-pane { display: none; }
  .sk-chat-list { border-right: 0; }
  .sk-chat-back { display: inline-flex; }
  .sk-bubble { max-width: 86%; }
}
@media (prefers-reduced-motion: reduce) {
  .sk-bubble, .sk-live-dot, .sk-typing-dots i { animation: none !important; }
}

/* ---- People: a clickable person, the profile popover, the people search ------------------ */

/* avatar + name as ONE button: no chrome of its own, the name underlines on hover / focus */
.sk-person {
  display: inline-flex; align-items: center; gap: 10px; min-width: 0; max-width: 100%;
  padding: 0; margin: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left;
  border-radius: 10px; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: opacity var(--sk-dur-fast);
}
.sk-person:active { opacity: .8; }
.sk-person-grow { flex: 1 1 auto; }
.sk-chat-head-who { gap: 12px; flex: 0 1 auto; }
.sk-person-text { display: flex; flex-direction: column; min-width: 0; }
.sk-person-name { font-size: 14px; font-weight: 500; line-height: 1.3; color: var(--g-100); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk-person-sub { font-size: 12px; line-height: 1.35; color: var(--g-500); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk-person:hover :is(.sk-person-name, .ar-row-name, .ar-board-name, .ar-twin-name, .sk-chat-head-name),
.sk-person:focus-visible :is(.sk-person-name, .ar-row-name, .ar-board-name, .ar-twin-name, .sk-chat-head-name) {
  text-decoration: underline; text-decoration-color: rgba(255,255,255,.38); text-underline-offset: 3px;
}

/* the profile popover (one for the whole app, see components/profileViewer.js) */
.sk-profile-head { display: flex; align-items: flex-start; gap: 14px; }
.sk-profile-id { min-width: 0; flex: 1; padding-top: 2px; }
.sk-profile-name { font-size: 17px; font-weight: 600; line-height: 1.25; color: var(--g-50); overflow-wrap: anywhere; }
.sk-profile-handle { margin-top: 2px; font: 500 13px/1.3 var(--font-mono); color: var(--signal-hi); overflow-wrap: anywhere; }
.sk-profile-role { margin-top: 3px; font-size: 13px; line-height: 1.35; color: var(--g-400); overflow-wrap: anywhere; }
.sk-profile-close {
  flex-shrink: 0; width: 28px; height: 28px; margin: -4px -6px 0 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 8px; background: none; color: var(--g-500); cursor: pointer;
  transition: color var(--sk-dur-fast), background var(--sk-dur-fast);
}
.sk-profile-close:hover { color: var(--g-200); background: rgba(255,255,255,.06); }
.sk-profile-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.sk-pchip {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 500; color: var(--g-300); background: rgba(0,0,0,.28); border: 1px solid var(--hair);
}
.sk-profile-bio { margin: 14px 0 0; font-size: 14px; line-height: 1.55; color: var(--g-300); white-space: pre-wrap; overflow-wrap: anywhere; }
.sk-profile-bio-empty { color: var(--g-500); font-style: italic; }
.sk-profile-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid rgba(0,0,0,.3);
}
/* Arena numbers on the popover: a small display window, three readouts */
.sk-pstats {
  display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, .8fr) minmax(0, 1.4fr); margin-top: 14px; overflow: hidden;
  border-radius: 12px; background: var(--well); border: 1px solid rgba(0,0,0,.6); box-shadow: var(--sh-well);
}
.sk-pstat { min-width: 0; padding: 10px 12px; }
.sk-pstat + .sk-pstat { border-left: 1px solid var(--hair); }
.sk-pstat-label { font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--g-500); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sk-pstat-value { margin-top: 5px; font: 500 20px/1.1 var(--font-mono); font-variant-numeric: tabular-nums slashed-zero; letter-spacing: -.02em; color: var(--g-50); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* "Find people" on the Friends page */
.sk-find-wrap { margin-bottom: 20px; }
.sk-find { transition: border-color var(--sk-dur-fast), box-shadow var(--sk-dur-fast); }
.sk-find:focus-within { border-color: rgba(255,106,31,.55); box-shadow: var(--sh-well), 0 0 0 3px rgba(255,106,31,.14); }
.sk-find input { min-width: 0; font-size: 14.5px; }
/* the box itself shows focus (the ring on the label); the bare input must not draw a second one */
.sk-find input:focus-visible { outline: none; }
.sk-find-clear {
  display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  border: 0; border-radius: 7px; background: rgba(255,255,255,.06); color: var(--g-400); cursor: pointer;
  transition: color var(--sk-dur-fast), background var(--sk-dur-fast);
}
.sk-find-clear:hover { color: var(--g-100); background: rgba(255,255,255,.12); }
.sk-find-hint { margin: 8px 2px 0; font-size: 12px; color: var(--g-500); }
.sk-results { transition: opacity var(--sk-dur-fast); }
.sk-results-busy { opacity: .55; }
@media (prefers-reduced-motion: reduce) {
  .sk-person, .sk-profile-close, .sk-find, .sk-find-clear, .sk-results { transition: none !important; }
}

/* ---- sign-in / sign-up: Google, phone, the method switch ---- */
.au-google { width: 100%; height: 44px; gap: 10px; }
.au-or { display: flex; align-items: center; gap: 12px; margin: 18px 0; font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--g-500); }
.au-or::before, .au-or::after { content: ""; flex: 1; height: 1px; background: var(--hair-2); }

/* Swipe between tabs (lib/swipeTabs.js): while a page has tabs, the browser leaves horizontal pans on the content to us and keeps
   vertical scrolling and pinch-zoom. Sideways-scrolling strips and tables are their own scroll containers and are not affected. */
[data-swipe-tabs] #app { touch-action: pan-y pinch-zoom; }
