/* The theme switch, one component in all five themes: the "Theme" pill (.theme-toggle) and the picker it opens
   (.theme-picker, five preview cards). theme.js builds both. Loaded by the main routes (THEME_HEAD in
   src/lib/theme.mjs) and by the OS, PRO and NOIR pages. Shape, size, parts and spacing live here; each theme
   only sets the --ts-* colours and fonts below (CUTE: these defaults; CODE: code/base.css; OS: os.css;
   PRO: pro/styles.css; NOIR: noir/style.css). Where it sits in each top bar is up to each theme's own CSS. */
:root {
  --ts-font: Figtree, system-ui, sans-serif;
  --ts-title: 800 18px/1.2 Fraunces, Georgia, serif;
  --ts-ink: var(--sb-ink, #33201A);
  --ts-body: var(--sb-body, #5A4C44);
  --ts-surface: #FFFDF9;
  --ts-hover: #F1F4E9;
  --ts-line: #9DAF91;
  --ts-panel-line: #D6C8B7;
  --ts-card: #FFFCF7;
  --ts-card-line: #E4DACD;
  --ts-card-hover: #F6F1E7;
  --ts-on-line: #8DA879;
  --ts-on: #F5F7EF;
  --ts-check: #779564;
  --ts-check-ink: #FFF;
  --ts-preview-line: rgba(62,48,44,.14);
  --ts-preview: #F8EFDF;
  --ts-shadow: 0 12px 32px rgba(62,48,44,.18);
  --ts-hint-shadow: 0 6px 18px rgba(62,48,44,.12);
  --ts-backdrop: rgba(51,32,26,.32);
  --ts-grabber: #D3C9BD;
  --ease-out: cubic-bezier(.23, 1, .32, 1);
}
body:has(.theme-control) { overflow-anchor: none; }
.theme-control { position: relative; flex: none; align-self: center; z-index: 5; letter-spacing: normal; text-shadow: none; }
.theme-preview {
  display: block;
  overflow: hidden;
  border: 1px solid var(--ts-preview-line);
  border-radius: 8px;
  background: var(--ts-preview);
}
.theme-preview img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* picker cards fade their preview in once it is decoded (theme.js), so no card pops in half drawn */
.theme-picker .theme-preview img { opacity: 0; transition: opacity .2s; }
.theme-picker .theme-preview img.is-loaded { opacity: 1; }
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  box-sizing: border-box;
  width: 128px; /* one size in every skin and language: skins change colour and font family only */
  height: 44px;
  margin: 0;
  padding: 5px 12px 5px 6px;
  border: 1px solid var(--ts-line);
  border-radius: 999px;
  background: var(--ts-surface);
  color: var(--ts-ink);
  font: 700 14px/1 var(--ts-font);
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .2s var(--ease-out), border-color .2s, color .2s, transform .25s var(--ease-out);
}
.theme-toggle:active { transform: translateY(1px) scale(.97); transition-duration: 80ms; }
.theme-toggle__label { flex: 1; font-size: 14px; letter-spacing: normal; text-align: left; }
.theme-toggle::after { content: ""; width: 7px; height: 7px; margin: -4px 1px 0 2px; border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: translateY(0) rotate(45deg); transition: transform .25s var(--ease-out); }
.theme-toggle[aria-expanded="true"]::after { transform: translateY(3px) rotate(225deg); }
.theme-toggle:hover, .theme-toggle[aria-expanded="true"] { background: var(--ts-hover); }
.theme-toggle__swatch { display: block; flex: none; width: 32px; height: 30px; }
.theme-toggle__swatch .theme-preview { box-sizing: border-box; width: 100%; height: 100%; border-radius: 9px; font-size: 9px; }
.theme-picker {
  box-sizing: border-box;
  position: absolute;
  inset: calc(100% + 12px) 0 auto auto;
  z-index: 51;
  width: 416px;
  max-width: calc(100vw - 32px);
  max-height: calc(100dvh - 100px);
  margin: 0;
  padding: 12px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--ts-panel-line);
  border-radius: 18px;
  background: var(--ts-surface);
  color: var(--ts-ink);
  box-shadow: var(--ts-shadow);
  font-family: var(--ts-font);
  text-align: left;
}
.theme-picker:not([open]) { display: none; }
.theme-picker::backdrop { background: var(--ts-backdrop); }
.theme-picker__heading { display: none; }
.theme-picker__close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  font: 400 28px/1 system-ui, sans-serif;
  text-transform: none;
  cursor: pointer;
}
.theme-picker .theme-switch {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
.theme-picker .theme-switch > button {
  position: relative;
  display: grid;
  grid-template-columns: 106px minmax(0, 1fr) 22px;
  align-items: center;
  gap: 12px;
  box-sizing: border-box;
  width: 100%;
  min-width: 44px;
  min-height: 88px;
  margin: 0;
  padding: 10px;
  border: 1px solid var(--ts-card-line);
  border-radius: 13px;
  background: var(--ts-card);
  color: var(--ts-ink);
  font: 700 12px/1.3 var(--ts-font);
  letter-spacing: normal;
  text-align: left;
  text-transform: none;
  white-space: normal;
  cursor: pointer;
}
.theme-picker .theme-switch > button[hidden] { display: none; }
.theme-picker .theme-switch > button:hover { background: var(--ts-card-hover); }
.theme-picker .theme-switch > [aria-checked="true"] { border-color: var(--ts-on-line); background: var(--ts-on); }
.theme-picker .theme-switch > button > .theme-preview { display: grid; width: 106px; height: 64px; }
.theme-switch__copy { display: block; min-width: 0; }
.theme-picker .theme-switch__name { display: block; font: var(--ts-title); }
.theme-picker .theme-switch__description { display: block; margin-top: 5px; color: var(--ts-body); font: 400 13px/1.4 var(--ts-font); }
.theme-picker .theme-switch__check { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; }
.theme-picker [aria-checked="true"] > .theme-switch__check { background: var(--ts-check); color: var(--ts-check-ink); }
.theme-picker [aria-checked="true"] > .theme-switch__check::after { content: ""; width: 9px; height: 5px; margin-top: -3px; border: solid currentColor; border-width: 0 0 2px 2px; transform: rotate(-45deg); }
.theme-picker__hint {
  box-sizing: border-box;
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  width: max-content;
  max-width: min(248px, calc(100vw - 32px));
  padding: 10px 13px;
  border: 1px solid var(--ts-panel-line);
  border-radius: 12px;
  background: var(--ts-surface);
  color: var(--ts-ink);
  box-shadow: var(--ts-hint-shadow);
  font: 600 13px/1.4 var(--ts-font);
  pointer-events: none;
}
.theme-picker__hint:empty { display: none; }
.theme-picker__hint:not(:empty)::before { content: ""; position: absolute; top: -5px; right: 24px; width: 8px; height: 8px; border: solid var(--ts-panel-line); border-width: 1px 0 0 1px; background: inherit; transform: rotate(45deg); }
.theme-switch :is(button:focus, button:focus-visible), .theme-toggle:focus, .theme-toggle:focus-visible, .theme-picker:focus, .theme-picker__close:focus, .theme-picker__close:focus-visible { outline: none; box-shadow: none; }
@media (max-width: 700px) {
  html.theme-sheet-open { overflow: hidden; }
  /* phones: a labelled pill, so the switch reads as "Theme" and not as a mystery dot */
  .theme-toggle { width: 120px; padding: 5px 13px 5px 6px; gap: 8px; }
  .theme-toggle__swatch { width: 30px; height: 30px; }
  .theme-picker {
    position: fixed;
    inset: auto 0 0;
    width: 100%;
    max-width: none;
    max-height: calc(100dvh - var(--sb-h, 60px) - 16px);
    padding: 8px 16px max(16px, env(safe-area-inset-bottom));
    border-radius: 24px 24px 0 0;
  }
  .theme-picker::before { content: ""; display: block; width: 44px; height: 4px; margin: 0 auto 5px; border-radius: 4px; background: var(--ts-grabber); }
  .theme-picker__heading { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; font: var(--ts-title); font-size: 24px; }
  .theme-picker .theme-switch { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .theme-picker .theme-switch > button { display: flex; flex-direction: row; align-items: center; justify-content: flex-start; gap: 14px; min-width: 0; min-height: 44px; padding: 10px 44px 10px 10px; text-align: left; }
  .theme-picker .theme-switch > button > .theme-preview { flex: none; width: 96px; height: auto; aspect-ratio: 16 / 9; }
  .theme-picker .theme-switch__name { font-size: 17px; }
  .theme-picker .theme-switch__description { margin-top: 4px; font-size: 13px; }
  .theme-picker .theme-switch__check { position: absolute; top: 50%; right: 14px; margin-top: -11px; }
  /* phones: nothing may rest on the page, so the hint is only announced */
  .theme-picker__hint { width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
}
/* Back to top (theme.js): bottom right on every page but the OS; hidden while a menu, the theme sheet or the NOIR
   poster viewer is open. Theme rules in this file stay CUTE-only (tests/theme.cjs), so the plain rule is CODE's
   terminal key from its --cd-* colours (set only in CODE), and every other page drops it: PRO and NOIR take their
   --ts-* colours, CUTE its cream and ink. */
.to-top {
  position: fixed;
  right: calc(24px + env(safe-area-inset-right));
  bottom: calc(24px + env(safe-area-inset-bottom));
  z-index: 30;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  border: 1px solid var(--cd-eren);
  border-radius: 4px;
  background: var(--cd-void);
  color: var(--cd-eren);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity .2s, transform .2s, visibility 0s .2s;
}
.to-top:hover { background: var(--cd-panel); }
.to-top.is-shown { opacity: 1; visibility: visible; transform: none; transition: opacity .2s, transform .2s; }
:is(html.theme-sheet-open, html.menu-open, body.menu-open, body:has(> .header.sb-open), html:has(.np-view[open])) .to-top { opacity: 0; visibility: hidden; }
.to-top:focus { outline: none; }
.to-top:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
html:not([data-theme="code"]) .to-top { border-color: var(--ts-line); border-radius: 50%; background: var(--ts-surface); color: var(--ts-ink); box-shadow: 0 4px 14px rgba(13, 27, 42, .14); }
html:not([data-theme="code"]) .to-top:hover { background: var(--ts-hover); }
html:not([data-theme="code"])[data-theme="cute"] .to-top { border: 1.5px solid var(--sb-ink, #33201A); background: #FFFDF9; box-shadow: 0 6px 16px rgba(62,48,44,.16); }
html:not([data-theme="code"])[data-theme="cute"] .to-top:hover { background: #F6F1E7; }
@media (min-width: 1001px) {
  /* CODE: above its motion pill on the right edge (code/base.css), so it stays in the margin */
  .to-top { bottom: calc(148px + env(safe-area-inset-bottom)); }
  html:not([data-theme="code"]) .to-top { bottom: calc(24px + env(safe-area-inset-bottom)); }
}
@media (max-width: 700px) {
  .to-top { right: calc(16px + env(safe-area-inset-right)); bottom: calc(16px + env(safe-area-inset-bottom)); }
  /* above the CUTE Axis page's call bar */
  html:not([data-theme="code"]) body.axis-case .to-top { bottom: calc(96px + env(safe-area-inset-bottom)); }
  html:not([data-theme="code"])[data-theme="cute"] .to-top.is-tucked { opacity: 0; visibility: hidden; }
}
:where(html.calm) .theme-control, :where(html.calm) .theme-control *, :where(html.calm) .theme-control *::before, :where(html.calm) .theme-control *::after { animation: none !important; transition: none !important; }
:where(html.calm) .to-top { transition: none; }
/* Less motion / More motion (theme.js): a text button beside the English · Türkçe links, in the footer bar and the
   phone menu of CUTE, CODE, PRO and NOIR. Its label is the action: html.calm shows More motion. Each theme sets its type. */
.motion-switch { margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
html.calm .motion-less, html:not(.calm) .motion-more { display: none; }
.motion-switch:focus { outline: none; }
.motion-switch:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 2px; }
@media (forced-colors: active) {
  .theme-toggle, .theme-picker, .theme-picker__hint, .theme-picker .theme-switch > button { border-color: CanvasText; background: Canvas; color: CanvasText; box-shadow: none; }
  .theme-picker .theme-switch__description { color: CanvasText; }
  .theme-picker .theme-switch > [aria-checked="true"] { border-color: Highlight; }
  .theme-picker [aria-checked="true"] > .theme-switch__check { forced-color-adjust: none; background: Highlight; color: HighlightText; }
  .theme-picker__hint:not(:empty)::before { border-color: CanvasText; }
}

/* ===== Switch transitions =====
   Every switch plays its destination's entrance, and the old page leaves into it. theme-transition.js gives the
   view transition the types fb-switch and into-<theme> (theme.js only for a switch), so no other navigation is touched.
   Only transform, opacity and clip-path animate. .fb-vt holds the overlay parts (CODE's CRT line, scanline and
   flicker, PRO's colour band); each part is its own view-transition group (fb-vt-1, -2, -3), so it runs on the
   transition's own clock. Durations: CUTE 800ms, CODE 750ms, OS 800ms, PRO 750ms, NOIR 780ms; phones about 20% less.
   Calm (html.calm, the motion switch): theme-transition.js skips the cross-page transition, and theme.js switches in
   place without one. */
@media screen {
  @view-transition { navigation: auto; }
}
html.fb-switching body > .header { view-transition-name: none; transition: none; }
html:active-view-transition-type(into-cute) { --fb-d: 800ms; }
html:active-view-transition-type(into-code) { --fb-d: 750ms; }
html:active-view-transition-type(into-os) { --fb-d: 800ms; }
html:active-view-transition-type(into-pro) { --fb-d: 750ms; }
html:active-view-transition-type(into-noir) { --fb-d: 780ms; }
@media (max-width: 700px) {
  html:active-view-transition-type(into-cute) { --fb-d: 640ms; }
  html:active-view-transition-type(into-code) { --fb-d: 620ms; }
  html:active-view-transition-type(into-os) { --fb-d: 640ms; }
  html:active-view-transition-type(into-pro) { --fb-d: 600ms; }
  html:active-view-transition-type(into-noir) { --fb-d: 640ms; }
}
html:active-view-transition-type(fb-switch)::view-transition-group(*) { animation: none; }
html:active-view-transition-type(fb-switch)::view-transition-old(*),
html:active-view-transition-type(fb-switch)::view-transition-new(*) { mix-blend-mode: normal; animation: none; }
.fb-vt { position: fixed; inset: 0; z-index: 2147483647; overflow: hidden; pointer-events: none; contain: strict; }
.fb-vt i { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.fb-vt i:nth-child(1) { view-transition-name: fb-vt-1; }
.fb-vt i:nth-child(2) { view-transition-name: fb-vt-2; }
.fb-vt i:nth-child(3) { view-transition-name: fb-vt-3; }

/* CUTE, page turn: the old page swings away on its left edge like a storybook page, CUTE comes up from its shade. */
html:active-view-transition-type(into-cute)::view-transition { background: #2b1d14; }
html:active-view-transition-type(into-cute)::view-transition-old(root) { z-index: 1; transform-origin: 0 50%; backface-visibility: hidden; animation: fb-turn var(--fb-d) cubic-bezier(.45, .05, .35, 1) both; }
html:active-view-transition-type(into-cute)::view-transition-new(root) { animation: fb-under var(--fb-d) cubic-bezier(.3, 0, .2, 1) both; }
@keyframes fb-turn { from { transform: perspective(1800px) rotateY(0); } to { transform: perspective(1800px) rotateY(-92deg); } }
@keyframes fb-under { from { opacity: .45; transform: scale(.98); } to { opacity: 1; transform: none; } }

/* CODE, terminal boot: the old screen collapses to a bright line and a dot (CRT off), then CODE scans in from the
   top behind a thin green scanline, with one soft flicker: a 6% green glow and a single dip, never a full-screen flash. */
html:active-view-transition-type(into-code)::view-transition { background: #040605; }
html:active-view-transition-type(into-code)::view-transition-old(root) { z-index: 1; animation: fb-crt-off var(--fb-d) linear both; }
html:active-view-transition-type(into-code)::view-transition-new(root) { animation: fb-scan-in var(--fb-d) linear both; }
@keyframes fb-crt-off {
  0% { transform: none; animation-timing-function: cubic-bezier(.6, 0, .9, .5); }
  30% { transform: scale(1, .004); opacity: 1; }
  40%, 100% { transform: scale(0, .004); opacity: 0; }
}
@keyframes fb-scan-in {
  0%, 44% { clip-path: inset(0 0 100% 0); opacity: 1; }
  50% { opacity: .82; } 56% { opacity: 1; }
  100% { clip-path: inset(0 0 0 0); opacity: 1; }
}
.fb-vt[data-into="code"] i:nth-child(1) { top: 50%; height: 2px; margin-top: -1px; background: #eafff1; box-shadow: 0 0 12px 2px rgba(57, 255, 140, .5); }
.fb-vt[data-into="code"] i:nth-child(2) { height: 12vh; background: linear-gradient(rgba(57, 255, 140, 0), rgba(57, 255, 140, .12) 85%, rgba(217, 255, 230, .8) calc(100% - 2px)); }
.fb-vt[data-into="code"] i:nth-child(3) { background: rgba(40, 255, 130, .06); }
html:active-view-transition-type(into-code)::view-transition-new(fb-vt-1) { animation: fb-crt-line var(--fb-d) linear both; }
html:active-view-transition-type(into-code)::view-transition-new(fb-vt-2) { animation: fb-scanline var(--fb-d) linear both; }
html:active-view-transition-type(into-code)::view-transition-new(fb-vt-3) { animation: fb-flicker var(--fb-d) linear both; }
@keyframes fb-crt-line {
  0%, 18% { opacity: 0; transform: none; }
  28%, 30% { opacity: 1; transform: none; }
  40% { opacity: 1; transform: scaleX(0); }
  44%, 100% { opacity: 0; transform: scaleX(0); }
}
@keyframes fb-scanline {
  0%, 43% { opacity: 0; transform: translateY(-12vh); }
  44% { opacity: 1; transform: translateY(-12vh); }
  96% { opacity: 1; }
  100% { opacity: 0; transform: translateY(88vh); }
}
@keyframes fb-flicker { 0%, 44% { opacity: 0; } 50% { opacity: 1; } 56% { opacity: .4; } 64%, 100% { opacity: 0; } }

/* OS, becomes a window: the old page shrinks into a rounded window and settles into the desktop easing in behind.
   It stays opaque while it settles and fades out only over the last 18%, so there is no double exposure. */
html:active-view-transition-type(into-os)::view-transition { background: #1f1d47; }
html:active-view-transition-type(into-os)::view-transition-old(root) { z-index: 1; animation: fb-window var(--fb-d) both; }
html:active-view-transition-type(into-os)::view-transition-new(root) { animation: fb-desk var(--fb-d) cubic-bezier(.2, .7, .2, 1) both; }
@keyframes fb-window {
  0% { transform: none; clip-path: inset(0 round 0); animation-timing-function: cubic-bezier(.5, 0, .2, 1); }
  55% { transform: translateY(3vh) scale(.6); clip-path: inset(0 round 36px); opacity: 1; animation-timing-function: cubic-bezier(.4, 0, .6, 1); }
  82% { transform: translateY(6vh) scale(.54); clip-path: inset(0 round 40px); opacity: 1; animation-timing-function: linear; }
  100% { transform: translateY(7vh) scale(.52); clip-path: inset(0 round 40px); opacity: 0; }
}
@keyframes fb-desk { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: none; } }

/* PRO, colour sweep: a diagonal wipe reveals PRO, with its green-to-pink band riding the edge (the edge leans 40vh
   across the screen height, so the band is skewed by atan(.4) to match). */
html:active-view-transition-type(into-pro)::view-transition-new(root) { z-index: 1; animation: fb-wipe var(--fb-d) cubic-bezier(.65, 0, .35, 1) both; }
@keyframes fb-wipe {
  from { clip-path: polygon(-50vh 0, 0px 0, -40vh 100%, -50vh 100%); }
  to { clip-path: polygon(-50vh 0, calc(100vw + 40vh) 0, 100vw 100%, -50vh 100%); }
}
.fb-vt[data-into="pro"] i { left: -15vh; width: 30vh; transform-origin: 0 0; transform: skewX(-21.8deg); background: linear-gradient(90deg, rgba(15, 181, 126, 0), #0fb57e 30%, #ff4d8d 70%, rgba(255, 77, 141, 0)); }
html:active-view-transition-type(into-pro)::view-transition-new(fb-vt-1) { animation: fb-band var(--fb-d) cubic-bezier(.65, 0, .35, 1) both; }
@keyframes fb-band { from { transform: none; } to { transform: translateX(calc(100vw + 40vh)); } }

/* NOIR, lights down: the old page dims to black and recedes; after a beat of black NOIR fades up with a slight push-in. */
html:active-view-transition-type(into-noir)::view-transition { background: #000; }
html:active-view-transition-type(into-noir)::view-transition-old(root) { animation: fb-lights-out var(--fb-d) both; }
html:active-view-transition-type(into-noir)::view-transition-new(root) { animation: fb-stage-up var(--fb-d) both; }
@keyframes fb-lights-out {
  0% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.4, 0, .7, .2); }
  38%, 100% { opacity: 0; transform: scale(.94); }
}
@keyframes fb-stage-up {
  0%, 46% { opacity: 0; transform: scale(.96); animation-timing-function: cubic-bezier(.2, .7, .2, 1); }
  100% { opacity: 1; transform: none; }
}

/* ---- WOW round 9: the theme pill, its choices, Back to top and Less/More motion get the theme's ring, 2px out ---- */
html .theme-toggle:focus-visible, html .theme-switch button:focus-visible, html .theme-picker__close:focus-visible { outline: 2px solid var(--ts-ring, var(--ts-check)); outline-offset: 2px; }
html :is(.to-top, .motion-switch):focus-visible { outline-color: var(--ts-ring, var(--ts-check)); outline-offset: 2px; }

/* ---- WOW round 13: the picker as a showroom. It unfolds from the pill's corner (phones: the sheet rises), the cards
   arrive one by one and the current one ticks; each card shows its theme's own colour on hover and keyboard focus; the
   pill fans a deck of the five previews on hover; a pick presses its card and ticks (theme.js .is-picked, 120 ms).
   All new motion runs only without html.calm and plays once. ---- */
:root { --tp-ease: cubic-bezier(.75, 0, .21, .99); }
.theme-picker .theme-switch > [value="cute"] { --tp-edge: linear-gradient(90deg, #8DA879, #EE8FB3); --tp-glow: rgba(238, 143, 179, .4); }
.theme-picker .theme-switch > [value="code"] { --tp-edge: #5DFF9E; --tp-glow: rgba(93, 255, 158, .36); }
.theme-picker .theme-switch > [value="os"] { --tp-edge: linear-gradient(90deg, #4F45C9, #B48CF2); --tp-glow: rgba(120, 100, 232, .42); }
.theme-picker .theme-switch > [value="pro"] { --tp-edge: linear-gradient(90deg, #0FB57E, #FF4D8D); --tp-glow: rgba(15, 181, 126, .34); }
.theme-picker .theme-switch > [value="noir"] { --tp-edge: var(--ts-ink); --tp-glow: color-mix(in srgb, var(--ts-ink) 30%, transparent); }
.theme-picker .theme-switch > button::after { content: ""; position: absolute; right: 14px; bottom: -1px; left: 14px; height: 2px; border-radius: 2px; background: var(--tp-edge); transform: scaleX(var(--tp-on, 0)); transform-origin: 0 50%; pointer-events: none; }
.theme-picker .theme-switch > button > .theme-preview { position: relative; transform: translateY(calc(var(--tp-on, 0) * -2px)); box-shadow: 0 calc(var(--tp-on, 0) * 8px) calc(var(--tp-on, 0) * 16px) -8px rgba(0, 0, 0, .45); }
.theme-picker .theme-switch > button > .theme-preview img { transform: scale(calc(1 + var(--tp-on, 0) * .07)); }
.theme-picker .theme-switch > [value="noir"] > .theme-preview::after { content: ""; position: absolute; inset: 0; background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, .5) 50%, transparent 70%); transform: translateX(-110%); pointer-events: none; }
.theme-picker .theme-switch > button:focus-visible { --tp-on: 1; box-shadow: 0 10px 24px -14px var(--tp-glow), 0 0 0 1px var(--tp-glow); }
@media (hover: hover) and (pointer: fine) {
  .theme-picker .theme-switch > button:hover { --tp-on: 1; box-shadow: 0 10px 24px -14px var(--tp-glow), 0 0 0 1px var(--tp-glow); }
  html:not(.calm) .theme-picker .theme-switch > [value="noir"]:hover > .theme-preview::after { animation: tp-sweep .8s var(--tp-ease); }
}
html:not(.calm) .theme-picker .theme-switch > [value="noir"]:focus-visible > .theme-preview::after { animation: tp-sweep .8s var(--tp-ease); }
html:not(.calm) .theme-picker .theme-switch > button { transition: background-color .2s, border-color .2s, box-shadow .3s var(--tp-ease), transform .12s var(--tp-ease); }
html:not(.calm) .theme-picker .theme-switch > button::after { transition: transform .32s var(--tp-ease); }
html:not(.calm) .theme-picker .theme-switch > button > .theme-preview { transition: transform .3s var(--tp-ease), box-shadow .3s var(--tp-ease); }
html:not(.calm) .theme-picker .theme-switch > button > .theme-preview img { transition: opacity .2s, transform .4s var(--tp-ease); }
@keyframes tp-sweep { from { transform: translateX(-110%); } to { transform: translateX(110%); } }

/* opening: opaque from the first frame (the clip reveals it), unfolding from the pill's corner on the house curve; closing stays instant */
html:not(.calm) .theme-picker[open] { animation: tp-unfold .28s var(--tp-ease) backwards; }
@keyframes tp-unfold {
  from { clip-path: inset(0 0 calc(100% - 12px) calc(100% - 128px) round 18px); transform: translateY(-6px); }
  to { clip-path: inset(-40px -40px -60px round 18px); transform: none; }
}
@keyframes tp-show { from { opacity: 0; } }
html:not(.calm) .theme-picker[open] .theme-switch > button { animation: tp-card .32s var(--tp-ease) backwards; }
html:not(.calm) .theme-picker[open] .theme-switch > button:nth-child(1) { animation-delay: 50ms; }
html:not(.calm) .theme-picker[open] .theme-switch > button:nth-child(2) { animation-delay: 85ms; }
html:not(.calm) .theme-picker[open] .theme-switch > button:nth-child(3) { animation-delay: 120ms; }
html:not(.calm) .theme-picker[open] .theme-switch > button:nth-child(4) { animation-delay: 155ms; }
html:not(.calm) .theme-picker[open] .theme-switch > button:nth-child(5) { animation-delay: 190ms; }
@keyframes tp-card { from { opacity: 0; transform: translateY(10px); } }
html:not(.calm) .theme-picker[open] [aria-checked="true"] > .theme-switch__check { animation: tp-pop .26s var(--tp-ease) .24s backwards; }
html:not(.calm) .theme-picker[open] [aria-checked="true"] > .theme-switch__check::after { animation: tp-draw .3s var(--tp-ease) .34s backwards; }
@keyframes tp-pop { from { opacity: 0; transform: scale(.4); } }
@keyframes tp-draw { from { clip-path: inset(0 100% 0 0); } }
@media (max-width: 700px) {
  html:not(.calm) .theme-picker[open] { animation: tp-rise .3s var(--tp-ease) backwards; }
  html:not(.calm) .theme-picker[open]::backdrop { animation: tp-show .2s linear backwards; }
}
@keyframes tp-rise { from { transform: translateY(100%); } }

/* a pick: the card presses and its check ticks while the switch begins; the old check steps back */
html:not(.calm) .theme-picker .theme-switch > .is-picked { transform: scale(.97); }
.theme-picker .is-picked > .theme-switch__check { background: var(--cd-eren, var(--ts-check)); color: var(--cd-void, var(--ts-check-ink)); }
.theme-picker .is-picked > .theme-switch__check::after { content: ""; width: 9px; height: 5px; margin-top: -3px; border: solid currentColor; border-width: 0 0 2px 2px; transform: rotate(-45deg); }
html:not(.calm) .theme-picker .is-picked > .theme-switch__check::after { animation: tp-draw .11s linear backwards; }
.theme-picker .theme-switch:has(.is-picked) > [aria-checked="true"]:not(.is-picked) > .theme-switch__check { opacity: 0; transition: opacity 90ms; }

/* the pill's deck (theme.js): on a fine-pointer hover the other four previews fan up and left from behind the swatch (the first child lies furthest back) */
.theme-toggle { position: relative; isolation: isolate; }
.theme-toggle__deck { position: absolute; top: 6px; left: 6px; z-index: -1; width: 32px; height: 30px; pointer-events: none; }
.theme-toggle__deck > .theme-preview { position: absolute; inset: 0; box-sizing: border-box; border-radius: 9px; opacity: 0; transform-origin: 50% 100%; box-shadow: 0 2px 6px rgba(0, 0, 0, .2); }
@media (hover: hover) and (pointer: fine) and (min-width: 701px) {
  html:not(.calm) .theme-toggle__deck > .theme-preview { transition: opacity .2s, transform .3s var(--tp-ease); }
  html:not(.calm) .theme-toggle:hover:not([aria-expanded="true"]) .theme-toggle__deck > .theme-preview { opacity: 1; }
  html:not(.calm) .theme-toggle:hover:not([aria-expanded="true"]) .theme-toggle__deck > :nth-child(1) { transform: translate(-8px, -6px) rotate(-16deg); transition-delay: 105ms; }
  html:not(.calm) .theme-toggle:hover:not([aria-expanded="true"]) .theme-toggle__deck > :nth-child(2) { transform: translate(-6px, -4.5px) rotate(-12deg); transition-delay: 70ms; }
  html:not(.calm) .theme-toggle:hover:not([aria-expanded="true"]) .theme-toggle__deck > :nth-child(3) { transform: translate(-4px, -3px) rotate(-8deg); transition-delay: 35ms; }
  html:not(.calm) .theme-toggle:hover:not([aria-expanded="true"]) .theme-toggle__deck > :nth-child(4) { transform: translate(-2px, -1.5px) rotate(-4deg); transition-delay: 0ms; }
}
@media (max-width: 700px) { .theme-toggle__deck { display: none; } }
