/* =========================================================================
   base.css — reset, design tokens, typography, layout, nav, primitives
   Loaded on every page. Page-specific rules live in tasks.css / timer.css.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Tokens
   ------------------------------------------------------------------------- */
:root {
  /* Void — the deepest tones of space */
  --void-900: #03040b;
  --void-800: #05060f;
  --void-700: #080b1a;
  --void-600: #0c1024;
  --void-500: #121731;

  /* Glass */
  --glass-1: rgba(255, 255, 255, 0.035);
  --glass-2: rgba(255, 255, 255, 0.055);
  --glass-3: rgba(255, 255, 255, 0.085);
  --stroke-1: rgba(255, 255, 255, 0.075);
  --stroke-2: rgba(255, 255, 255, 0.14);
  --stroke-3: rgba(255, 255, 255, 0.22);

  /* Ink */
  --ink-1: #eef1fb;
  --ink-2: #b6bdd8;
  --ink-3: #7d86a6;
  --ink-4: #545c78;

  /* Accents — calm, cool, low-saturation */
  --accent-1: #8fb4ff;
  --accent-2: #b78cff;
  --accent-3: #6fd8cf;
  --accent-4: #ff9db4;
  --accent-1-rgb: 143, 180, 255;

  /* Typography */
  /* One family, both tokens. Victor Mono is monospaced, so a proportional
     fallback would reflow differently on failure; the system mono stack below
     keeps every glyph on the same grid, which is what this design expects. */
  --font-sans: 'Victor Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo,
    Consolas, 'Liberation Mono', monospace;
  --font-mono: 'Victor Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo,
    Consolas, 'Liberation Mono', monospace;

  /* Geometry */
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 999px;

  /* Elevation */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
  --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.34), 0 24px 60px -28px rgba(0, 0, 0, 0.85);
  --shadow-3: 0 4px 14px rgba(0, 0, 0, 0.4), 0 48px 110px -40px rgba(0, 0, 0, 0.9);

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.5, 1);
  --t-fast: 140ms;
  --t-med: 280ms;
  --t-slow: 560ms;

  /* Layout */
  --nav-h: 68px;
  --measure: 760px;
  --gutter: clamp(1.15rem, 4vw, 2rem);

  color-scheme: dark;
}

/* -------------------------------------------------------------------------
   2. Reset
   ------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--void-800);
  color: var(--ink-1);
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* -------------------------------------------------------------------------
   Page transitions.

   Two pages and no router, so the only honest way to soften the swap is a
   short crossfade: fade out on the way to a nav link, fade in on arrival.
   Animating the new page over the old one needs the View Transitions API and
   a same-document render, which is a lot of machinery for a two-page site.

   The fade-in is declared here rather than added by a script, so it also runs
   on a plain `file://` open and on any navigation where JS never gets to
   attach. `is-leaving` is the half JS adds, and only ever on a click that is
   definitely going to navigate.

   Deliberately short. A page transition you notice is one that is too slow,
   and this site's whole premise is that nothing tugs.
   ------------------------------------------------------------------------- */

body {
  animation: page-in 200ms var(--ease-out) both;
}

body.is-leaving {
  animation: page-out 150ms var(--ease-out) both;
  pointer-events: none;
}

@keyframes page-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes page-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

img,
svg,
canvas {
  display: block;
  max-width: 100%;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

/* The UA's `[hidden] { display: none }` loses to *any* author `display`, so a
   `.empty { display: flex }` would stay on screen while JS set `.hidden`.
   Everything that toggles `.hidden` in JS needs this to actually win. */
[hidden] {
  display: none !important;
}

ul,
ol {
  list-style: none;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

h1,
h2,
h3 {
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.15;
  text-wrap: balance;
}

kbd {
  font-family: var(--font-mono);
  font-size: 0.72em;
  padding: 0.15em 0.42em;
  border-radius: 5px;
  border: 1px solid var(--stroke-2);
  background: var(--glass-2);
  color: var(--ink-2);
  line-height: 1;
}

/* Focus — one consistent, visible ring everywhere */
:focus {
  outline: none;
}

:focus-visible {
  outline: 2px solid var(--accent-1);
  outline-offset: 3px;
  border-radius: 6px;
}

/* -------------------------------------------------------------------------
   3. Utilities
   ------------------------------------------------------------------------- */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: 0.6rem;
  left: 50%;
  translate: -50% -160%;
  z-index: 100;
  padding: 0.6rem 1.1rem;
  border-radius: var(--r-pill);
  background: var(--void-600);
  border: 1px solid var(--stroke-2);
  box-shadow: var(--shadow-2);
  font-size: 0.86rem;
  color: var(--ink-1);
  transition: translate var(--t-med) var(--ease-out);
}

.skip-link:focus-visible {
  translate: -50% 0;
}

.footnote {
  font-size: 0.8rem;
  color: var(--ink-4);
  text-align: center;
  text-wrap: balance;
  padding: 0 0.5rem;
}

/* -------------------------------------------------------------------------
   4. Layout
   ------------------------------------------------------------------------- */
.page {
  flex: 1;
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding: clamp(2rem, 7vw, 4rem) var(--gutter) 3rem;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: clamp(1.15rem, 3vw, 1.6rem);
}

.footer {
  padding: 1.6rem var(--gutter) 2.2rem;
  text-align: center;
}

.footer__text {
  font-size: 0.78rem;
  color: var(--ink-4);
  letter-spacing: 0.02em;
  display: inline-flex;
  gap: 0.5rem;
}

.footer__sep {
  opacity: 0.5;
}

/* The credit, on its own line so the footer reads as two thoughts rather than
   one crowded row. `display: block` deliberately overrides the inline-flex on
   `.footer__text`: flex would treat each word as an item and space them apart,
   which is right for "Mach · v1.0.0" and wrong for running prose. */
.footer__made {
  display: block;
  margin: 0.5rem 0 0;
}

.footer__link {
  color: var(--ink-3);
  text-decoration: none;
  border-bottom: 1px solid var(--stroke-2);
  transition:
    color var(--t-med) var(--ease-out),
    border-color var(--t-med) var(--ease-out);
}

.footer__link:hover {
  color: var(--ink-1);
  border-bottom-color: rgba(var(--accent-1-rgb), 0.6);
}

.footer__link:focus-visible {
  outline: 2px solid var(--accent-1);
  outline-offset: 3px;
  border-radius: 2px;
}

/* -------------------------------------------------------------------------
   5. Glass panel
   ------------------------------------------------------------------------- */
.panel {
  position: relative;
  border-radius: var(--r-xl);
  border: 1px solid var(--stroke-1);
  background: linear-gradient(180deg, var(--glass-2), var(--glass-1));
  box-shadow: var(--shadow-2), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(22px) saturate(140%);
  -webkit-backdrop-filter: blur(22px) saturate(140%);
  padding: clamp(1.1rem, 3vw, 1.5rem);
}

/* Hairline highlight along the top edge — reads as light catching glass */
.panel::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.28) 22%,
    rgba(255, 255, 255, 0.28) 78%,
    transparent
  );
  opacity: 0.7;
  pointer-events: none;
}

/* -------------------------------------------------------------------------
   6. Navigation
   ------------------------------------------------------------------------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 40;
  padding: clamp(0.7rem, 2vw, 1rem) var(--gutter) 0;
}

.nav__inner {
  max-width: 1080px;
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: calc(var(--nav-h) - 16px);
  min-height: 52px;
  padding: 0 0.5rem 0 0.9rem;
  border-radius: var(--r-lg);
  border: 1px solid var(--stroke-1);
  background: linear-gradient(180deg, rgba(12, 16, 36, 0.72), rgba(8, 11, 26, 0.58));
  box-shadow: var(--shadow-1), inset 0 1px 0 rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
}

/* Brand */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
  border-radius: var(--r-md);
}

.brand__mark {
  width: 30px;
  height: 30px;
  flex: none;
  color: var(--accent-1);
  filter: drop-shadow(0 0 10px rgba(var(--accent-1-rgb), 0.4));
  animation: brand-drift 14s var(--ease-in-out) infinite;
}

.brand__mark svg {
  width: 100%;
  height: 100%;
}

.brand__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.15;
}

.brand__name {
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.brand__tag {
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
}

@keyframes brand-drift {
  0%,
  100% {
    transform: rotate(-6deg) translateY(0);
  }
  50% {
    transform: rotate(4deg) translateY(-1.5px);
  }
}

/* Right-hand cluster: ambience, then the links */
.nav__right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

/* Links — animated pill */
.nav__links {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  padding: 0.25rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--stroke-1);
  background: rgba(0, 0, 0, 0.22);
}

.nav__link {
  position: relative;
  padding: 0.44rem 1rem;
  border-radius: var(--r-pill);
  font-size: 0.87rem;
  font-weight: 500;
  color: var(--ink-3);
  white-space: nowrap;
  transition: color var(--t-med) var(--ease-out);
}

.nav__link:hover {
  color: var(--ink-1);
}

.nav__link.is-active {
  color: var(--ink-1);
  background: linear-gradient(180deg, var(--glass-3), var(--glass-1));
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset, 0 4px 14px -6px rgba(0, 0, 0, 0.7);
}

.nav__link.is-active::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -0.55rem;
  translate: -50% 0;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent-1), var(--accent-2));
  box-shadow: 0 0 10px rgba(var(--accent-1-rgb), 0.6);
}

@media (max-width: 430px) {
  .brand__tag {
    display: none;
  }
  .nav__link {
    padding: 0.44rem 0.8rem;
  }
  /* The menu is the first thing to give up room: the toggle still says whether
     sound is on, and the list is one tap away on a phone anyway. */
  .ambience__button {
    max-width: 5.5rem;
  }
  .ambience__list {
    right: auto;
    left: 0;
    max-width: min(78vw, 15rem);
  }
}

/* -------------------------------------------------------------------------
   6b. Ambience
   -------------------------------------------------------------------------
   A toggle and a menu, in the nav, on both pages. Kept as small and dim as
   the feature is quiet — it should be findable when you want it and invisible
   when you don't.
   ------------------------------------------------------------------------- */
.ambience {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex: none;
}

.ambience__toggle {
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--stroke-1);
  background: rgba(0, 0, 0, 0.22);
  color: var(--ink-4);
  transition:
    color var(--t-med) var(--ease-out),
    border-color var(--t-med) var(--ease-out),
    background var(--t-med) var(--ease-out);
}

.ambience__toggle:hover {
  color: var(--ink-2);
  border-color: var(--stroke-2);
}

.ambience__toggle[aria-pressed='true'] {
  color: var(--accent-1);
  border-color: rgba(var(--accent-1-rgb), 0.4);
  background: rgba(var(--accent-1-rgb), 0.09);
  box-shadow: 0 0 14px -4px rgba(var(--accent-1-rgb), 0.6);
}

.ambience__icon {
  width: 19px;
  height: 19px;
  display: block;
}

/* Speaker plus waves when playing, speaker plus a cross when not. Two paths,
   one attribute, no icon font and no second asset to load. */
.ambience__cross,
.ambience__toggle[aria-pressed='true'] .ambience__wave {
  display: none;
}

.ambience__toggle[aria-pressed='true'] .ambience__cross {
  display: block;
}

/* The browser refused to autoplay. The button breathes until it is touched —
   one loop only, and the global reduced-motion rule flattens it to a single
   frame, so it cannot become the thing that tugs for attention. */
@keyframes ambience-wait {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(var(--accent-1-rgb), 0.5);
  }
  50% {
    box-shadow: 0 0 0 7px rgba(var(--accent-1-rgb), 0);
  }
}

.ambience__toggle[data-blocked='true'] {
  color: var(--accent-1);
  border-color: rgba(var(--accent-1-rgb), 0.4);
  animation: ambience-wait 2.6s var(--ease-out) 1;
}

/* The picker — a real button and a real listbox, not a <select>.
   The native control cannot be styled: on Windows and Android the popup is
   painted by the OS in the OS's own colours and metrics, so it arrives as a
   white rectangle with a system font in a site that is nothing but dark glass.
   Reproducing the look means not using the element, so this is the button and
   listbox pair instead — which is also the only way to group the eleven sounds
   under the four families they belong to. */
.ambience__picker {
  position: relative;
  min-width: 0;
}

.ambience__button {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 9rem;
  height: 34px;
  padding: 0 0.6rem 0 0.7rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--stroke-1);
  background: rgba(0, 0, 0, 0.22);
  color: var(--ink-3);
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  transition:
    color var(--t-med) var(--ease-out),
    border-color var(--t-med) var(--ease-out),
    background var(--t-med) var(--ease-out);
}

.ambience__button:hover {
  color: var(--ink-2);
  border-color: var(--stroke-2);
}

.ambience__button:focus-visible {
  outline: 2px solid var(--accent-1);
  outline-offset: 2px;
}

.ambience__button[aria-expanded='true'] {
  color: var(--ink-1);
  border-color: rgba(var(--accent-1-rgb), 0.4);
  background: rgba(var(--accent-1-rgb), 0.09);
}

.ambience__label {
  min-width: 0;
  /* The chosen name is longer than the control on a phone, so it truncates
     rather than pushing the nav wider than the screen. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ambience__chevron {
  flex: none;
  width: 11px;
  height: 11px;
  opacity: 0.6;
  transition: rotate var(--t-med) var(--ease-out);
}

.ambience__button[aria-expanded='true'] .ambience__chevron {
  rotate: 180deg;
}

/* The listbox. Anchored to the button's right edge, because the button is on
   the right of the nav and a left-anchored popup on a 360px phone runs off the
   edge. */
.ambience__list {
  position: absolute;
  z-index: 60;
  top: calc(100% + 0.45rem);
  right: 0;
  min-width: 12.5rem;
  max-width: min(72vw, 17rem);
  max-height: min(60vh, 19rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.3rem;
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, rgba(18, 23, 49, 0.97), rgba(8, 11, 26, 0.98));
  box-shadow: var(--shadow-3), inset 0 1px 0 rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  animation: ambience-list-in 150ms var(--ease-out) both;
}

@keyframes ambience-list-in {
  from {
    opacity: 0;
    translate: 0 -5px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

.ambience__group-label {
  padding: 0.5rem 0.55rem 0.28rem;
  font-size: 0.68rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.ambience__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.44rem 0.55rem;
  border-radius: var(--r-sm);
  font-size: 0.83rem;
  color: var(--ink-2);
  cursor: pointer;
  transition:
    background var(--t-fast) var(--ease-out),
    color var(--t-fast) var(--ease-out);
}

/* The name is its own element so it can truncate, leaving the tick pinned to
   the right edge instead of being shoved off the end of the row. */
.ambience__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Two states, and they mean different things: *active* is where the keyboard
   is, *selected* is what is playing. A user with the list open needs to see
   both — where they are and what they have. */
.ambience__option:hover,
.ambience__option.is-active {
  background: var(--glass-3);
  color: var(--ink-1);
}

.ambience__option[aria-selected='true'] {
  color: var(--accent-1);
  background: rgba(var(--accent-1-rgb), 0.1);
}

.ambience__option[aria-selected='true']:hover,
.ambience__option[aria-selected='true'].is-active {
  background: rgba(var(--accent-1-rgb), 0.18);
}

/* The tick only appears on the one that is actually playing, so "what is on"
   is a single glance down the list rather than a memory of the label. */
.ambience__tick {
  flex: none;
  width: 13px;
  height: 13px;
  opacity: 0;
}

.ambience__option[aria-selected='true'] .ambience__tick {
  opacity: 1;
}

.ambience__empty {
  padding: 0.6rem 0.55rem;
  font-size: 0.8rem;
  color: var(--ink-4);
}

/* -------------------------------------------------------------------------
   7. Buttons
   ------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--glass-2);
  --btn-fg: var(--ink-1);
  --btn-bd: var(--stroke-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.62rem 1.15rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--btn-bd);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: 0.88rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transition: transform var(--t-fast) var(--ease-out), background var(--t-med) var(--ease-out),
    border-color var(--t-med) var(--ease-out), opacity var(--t-med) var(--ease-out),
    box-shadow var(--t-med) var(--ease-out), color var(--t-med) var(--ease-out);
}

.btn:hover:not(:disabled) {
  background: var(--glass-3);
  border-color: var(--stroke-3);
}

.btn:active:not(:disabled) {
  transform: scale(0.965);
}

.btn:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}

.btn--primary {
  --btn-bd: transparent;
  background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
  color: #080b1a;
  font-weight: 600;
  box-shadow: 0 6px 22px -8px rgba(var(--accent-1-rgb), 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.btn--primary:hover:not(:disabled) {
  background: linear-gradient(135deg, #a3c1ff, #c39bff);
  border-color: transparent;
  box-shadow: 0 8px 30px -8px rgba(var(--accent-1-rgb), 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.4);
}

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink-2);
  --btn-bd: var(--stroke-1);
  padding: 0.5rem 0.85rem;
  font-size: 0.8rem;
}

.btn--ghost:hover:not(:disabled) {
  --btn-fg: var(--ink-1);
  --btn-bg: var(--glass-1);
}

.btn--danger:hover:not(:disabled) {
  --btn-fg: var(--accent-4);
  --btn-bd: rgba(255, 157, 180, 0.35);
  --btn-bg: rgba(255, 157, 180, 0.08);
}

/* Armed state for a two-step destructive confirm. */
.btn.is-armed {
  --btn-fg: var(--accent-4);
  --btn-bd: rgba(255, 157, 180, 0.5);
  --btn-bg: rgba(255, 157, 180, 0.12);
}

.btn--icon {
  padding: 0;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  color: var(--ink-2);
}

.btn--icon svg {
  width: 19px;
  height: 19px;
}

/* -------------------------------------------------------------------------
   8. Toggles
   ------------------------------------------------------------------------- */

/* Segmented pill with a sliding glider */
.modes {
  position: relative;
  display: flex;
  gap: 0.1rem;
  padding: 0.26rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--stroke-1);
  background: rgba(0, 0, 0, 0.26);
  isolation: isolate;
}

.modes__glider {
  position: absolute;
  z-index: -1;
  /* `left: 0` is load-bearing, not tidiness. Without it the glider falls back
     to its static position, which for an absolutely-positioned child of a flex
     container is the *content-box* start corner — 0.26rem in, past the padding.
     `translateX(offsetLeft)` then adds the tab's offset measured from the
     *padding* edge, so the two coordinate systems disagree by exactly the
     container's padding and every glider lands 0.26rem too far right. On the
     last tab that is enough to cross the container's own border. */
  left: 0;
  top: 0.26rem;
  bottom: 0.26rem;
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--glass-3), var(--glass-1));
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.09) inset, 0 6px 18px -8px rgba(0, 0, 0, 0.8);
  border: 1px solid var(--stroke-1);
  transition: transform var(--t-med) var(--ease-spring), width var(--t-med) var(--ease-spring);
  will-change: transform, width;
}

.modes__tab {
  flex: 1;
  padding: 0.44rem 0.9rem;
  border-radius: var(--r-pill);
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--ink-3);
  transition: color var(--t-med) var(--ease-out);
}

.modes__tab:hover {
  color: var(--ink-1);
}

.modes__tab.is-active {
  color: var(--ink-1);
  font-weight: 600;
}

.toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.8rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--stroke-1);
  background: transparent;
  font-size: 0.78rem;
  color: var(--ink-3);
  transition: color var(--t-med) var(--ease-out), border-color var(--t-med) var(--ease-out),
    background var(--t-med) var(--ease-out);
}

.toggle:hover {
  color: var(--ink-1);
  background: var(--glass-1);
}

.toggle__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-4);
  transition: background var(--t-med) var(--ease-out), box-shadow var(--t-med) var(--ease-out);
}

.toggle.is-on {
  color: var(--ink-1);
  border-color: var(--stroke-2);
  background: var(--glass-1);
}

.toggle.is-on .toggle__dot {
  background: var(--accent-1);
  box-shadow: 0 0 0 3px rgba(var(--accent-1-rgb), 0.16), 0 0 10px rgba(var(--accent-1-rgb), 0.8);
}

/* -------------------------------------------------------------------------
   9. Toast
   ------------------------------------------------------------------------- */
.toast {
  position: fixed;
  z-index: 60;
  left: 50%;
  bottom: max(1.5rem, env(safe-area-inset-bottom));
  translate: -50% 0;
  max-width: min(90vw, 30rem);
  padding: 0.65rem 1.1rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--stroke-2);
  background: rgba(12, 16, 36, 0.86);
  box-shadow: var(--shadow-2);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  font-size: 0.84rem;
  color: var(--ink-1);
  text-align: center;
  opacity: 0;
  transform: translateY(8px) scale(0.97);
  transition: opacity var(--t-med) var(--ease-out), transform var(--t-med) var(--ease-spring);
  pointer-events: none;
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* -------------------------------------------------------------------------
   10. Scrollbar
   ------------------------------------------------------------------------- */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
  background-color: rgba(255, 255, 255, 0.16);
}

::-webkit-scrollbar-thumb:hover {
  background-color: rgba(255, 255, 255, 0.28);
}

/* -------------------------------------------------------------------------
   11. Reduced motion
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  /* This covers the page crossfade and the mode-accent transition too: both
     are animations or transitions, and both are worth nothing to someone who
     asked for stillness. `bindPageTransitions` also declines to intercept the
     click at all, so reduced motion never even waits for a fade. */
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

