/*
 * Styles for the Fokus web app.
 *
 * Plain CSS on purpose. The app sits outside the site's Tailwind build so it
 * stays runnable on its own — open the folder on any machine and it works,
 * which is what makes testing on a stranger's computer cheap.
 *
 * Colours come from Theme.swift; see js/config.js for the citation of each.
 * Type and surfaces follow the website and the training slides: Plus Jakarta
 * Sans for headings, Inter for text, cards with a faint blue edge and glow.
 * The fonts come from the site (`/fonts/fonts.css`); opened on its own, the
 * app falls back to the system font and still works.
 */

/* MARK: - Tokens */

:root {
  --bg: #0B1322;
  --text: #E7E6E6;
  --accent: #0193DF;
  --accent-soft: #38bdf8;
  --green: #10B981;
  --green-soft: #34d399;
  --muted: #94a3b8;
  --card: rgba(16, 28, 50, 0.65);
  --card-border: rgba(56, 189, 248, 0.18);
  --card-lift: 0 0 0 1px rgba(56, 189, 248, 0.05), 0 0 30px -8px rgba(56, 189, 248, 0.22);
  --font-heading: "Plus Jakarta Sans", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --peak-scale: 1.23;
  --trough-scale: 0.63;
  --height-share: 0.70;

  --ease-breath: cubic-bezier(0.42, 0, 0.58, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
  color: var(--text);
  font: 400 17px/1.6 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* Two soft pools of the brand colours behind everything, as on the website's
   hero: enough to make the page feel lit, never enough to compete. On the
   root, so they sit behind every screen and stay put while the page scrolls. */
html {
  background:
    radial-gradient(60rem 40rem at 10% -10%, rgba(1, 147, 223, 0.16), transparent 60%),
    radial-gradient(50rem 36rem at 100% 110%, rgba(16, 185, 129, 0.12), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}

/* MARK: - Screens
   One screen is visible at a time: intro -> exercise -> completed. */

.screen { display: none; }
.screen[data-active] { display: grid; }

#screen-home,
#screen-intro,
#screen-setup,
#screen-running,
#screen-invite,
#screen-done {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  place-items: center;
  padding: 9vh 24px 6vh;
}

/* The completion screen is entered straight out of two minutes of breathing
   with the eyes shut. Meeting a wall of text there is a hard edge, so the words
   arrive slowly instead of instantly. */
#screen-done[data-active] .column > * {
  animation: settle 900ms ease-out both;
}

#screen-done[data-active] .column > *:nth-child(2) { animation-delay: 120ms; }
#screen-done[data-active] .column > *:nth-child(3) { animation-delay: 240ms; }
#screen-done[data-active] .column > *:nth-child(4) { animation-delay: 380ms; }

@keyframes settle {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* MARK: - The column

   A start screen is not a list. Everything used to sit in one rhythm at one
   weight — nine elements, all equally loud — and the eye found no way in. The
   column now has three tiers: what you came for, what you may adjust, and what
   is merely true. `--gap` sets the distance between tiers; the tiers set their
   own inner spacing. */

.column {
  max-width: 34rem;
  text-align: center;
  display: grid;
  gap: 26px;
  justify-items: center;
}

/* Tier 1 — the reason the page exists. Headline, the one control, the button. */
.column__lead {
  display: grid;
  gap: 14px;
  justify-items: center;
}

/* Tier 2 — offered, not pressed: settings and the permission. Held back by a
   hairline above rather than by more space, which would only make the page
   longer. */
.column__aside {
  display: grid;
  gap: 14px;
  justify-items: center;
  width: min(30rem, 100%);
  padding-top: 22px;
  border-top: 1px solid rgba(231, 230, 230, 0.10);
}

/* Tier 3 — true, and quiet about it. */
.column__foot {
  display: grid;
  gap: 8px;
  justify-items: center;
  margin-top: 4px;
}

h1 {
  margin: 0;
  font-family: var(--font-heading);
  font-size: clamp(32px, 5.4vw, 50px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: #fff;
}

/* The page that lists choices is wider than a page that asks one question. */
.column--wide { max-width: 46rem; width: 100%; }

.lead { margin: 0; opacity: 0.82; }

/* The small capitalised line above a heading, as the macOS overlays use it. */
.eyebrow {
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.45;
}

.fine {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  opacity: 0.4;
  max-width: 30rem;
}

.fine a { color: inherit; }

/* MARK: - Exercise stage */

#screen-exercise {
  position: fixed;
  inset: 0;
  background: var(--bg);
  place-items: center;
  z-index: 10;
}

#motif {
  /* Derived so that peak-scale x base covers 70 % of the usable height,
     exactly as BreathCircleMetrics derives it on macOS. `dvh` rather than `vh`
     because on a phone `100vh` counts the space behind the browser's own bars:
     the circle would be sized for a window taller than the one it is in. */
  --base: calc((100vh - 240px) * var(--height-share) / var(--peak-scale));
  --base: calc((100dvh - 240px) * var(--height-share) / var(--peak-scale));
  --trough: calc(var(--base) * var(--trough-scale));
  width: var(--base);
  height: var(--base);
  position: relative;
  display: grid;
  place-items: center;
}

/* Only transform and opacity are animated, and every layer shares one
   transition, so size and colour cannot drift apart. */
.breathes {
  transition-property: transform, opacity;
  transition-timing-function: var(--ease-breath);
  transition-duration: 0ms;
  will-change: transform, opacity;
}

.disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  transform: scale(var(--trough-scale));
}

/* The circle is drawn like the rest of the page — a tinted, translucent
   surface with a luminous edge — not as a solid disc of paint. It keeps the
   app's two colours, fokusblue to reliefgreen, but in the softer variants the
   slides use, so it sits among the cards instead of on top of them.
   **Deliberate departure from the macOS app**, which fills the disc solid
   (Theme.swift, BreathGradient). */

/* Full inhale: lit from within, edge bright, glow out into the room. */
#disc-lit {
  background:
    radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.16), transparent 55%),
    linear-gradient(135deg, rgba(56, 189, 248, 0.55), rgba(52, 211, 153, 0.50));
  box-shadow:
    inset 0 0 0 2px rgba(186, 230, 253, 0.45),
    0 0 50px -4px rgba(56, 189, 248, 0.45),
    0 0 110px -10px rgba(52, 211, 153, 0.35);
  opacity: 0;
}

/* Full exhale: the same surface, dimmed to a quiet tint with a thin edge.
   Deliberately short of the background: a circle that all but vanishes at
   the trough reads as a fault rather than as rest. */
#disc-deep {
  background: linear-gradient(135deg, rgba(1, 147, 223, 0.22), rgba(16, 185, 129, 0.18));
  box-shadow: inset 0 0 0 1.5px rgba(56, 189, 248, 0.35);
  opacity: 1;
}

#glow {
  position: absolute;
  inset: -40%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(56, 189, 248, 0.14) 0%, rgba(16, 185, 129, 0.08) 40%, transparent 70%);
  filter: blur(40px);
  transform: scale(calc(var(--trough-scale) * 1.3));
  pointer-events: none;
}

/* MARK: - Labels inside the circle
   Type is measured against the circle at its smallest, so it still sits inside
   the disc at full exhale. */

#labels {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 6px;
  justify-items: center;
  max-width: calc(var(--trough) * 0.66);
  text-align: center;
}

#instruction {
  font-size: clamp(24px, calc(var(--trough) * 0.15), 56px);
  font-weight: 700;
  white-space: nowrap;
  opacity: 0.92;
}

/* A label that carries its own line break, such as the lead-in. Set from
   script whenever the translated string contains a newline, so any string can
   opt into stacking without the code knowing which one it is. */
#instruction.is-stacked {
  white-space: pre-line;
  line-height: 1.1;
}

#countdown {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-size: clamp(40px, calc(var(--trough) * 0.26), 104px);
  font-weight: 700;
  line-height: 1.05;
  min-height: 1.05em;
  opacity: 0.92;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

#counter {
  position: absolute;
  top: 6vh;
  font-size: 14px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
}

#exercise-controls {
  position: absolute;
  bottom: 6vh;
  display: grid;
  gap: 14px;
  justify-items: center;
}

#escape-hint {
  font-size: 13px;
  opacity: 0.32;
}

/* MARK: - Controls */

.button {
  font: inherit;
  font-weight: 500;
  color: var(--text);
  background: transparent;
  border: 1px solid rgba(231, 230, 230, 0.35);
  border-radius: 999px;
  padding: 12px 30px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-decoration: none;
  transition: border-color 160ms, background-color 160ms, transform 160ms, box-shadow 160ms;
}

.button:hover {
  border-color: rgba(231, 230, 230, 0.7);
  background-color: rgba(231, 230, 230, 0.06);
}

/* Filled, not outlined: the one thing on the screen meant to be pressed
   should look pressable from across the room. */
.button--primary {
  border-color: transparent;
  background: linear-gradient(135deg, #0193DF, #0170A8);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 8px 28px -10px rgba(1, 147, 223, 0.7);
}

.button--primary:hover {
  border-color: transparent;
  background: linear-gradient(135deg, #12A3EE, #0193DF);
  transform: translateY(-1px);
  box-shadow: 0 12px 32px -10px rgba(1, 147, 223, 0.85);
}

.button--large { padding: 16px 38px; font-size: 18px; }
.button--small { padding: 10px 20px; font-size: 15px; }
.button .icon { width: 1.15em; height: 1.15em; }


.button--quiet {
  border: none;
  padding: 8px 14px;
  font-size: 14px;
  opacity: 0.6;
}

.button--quiet:hover { opacity: 1; background-color: transparent; }

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

.row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
}

/* MARK: - Timer */

.choice {
  border: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  justify-items: center;
}

.choice legend {
  float: left;
  width: 100%;
  padding: 0 0 10px;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
  text-align: center;
}

/* The chosen length, shown above the slider so the thumb never covers it. */
#duration-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 34px;
  font-weight: 500;
  color: #fff;
}

#duration { width: min(20rem, 70vw); }

/* MARK: - The countdown ring

   The arc carries the time and the digits name it. Green rather than the
   signature blue, and deliberately *not* turning amber or red near the end:
   the app picked green so the countdown "reads as information, not as an
   alarm" (Theme.swift), and a working timer that starts shouting at minute 24
   is a timer people close. */

#ring-wrap {
  position: relative;
  container-type: inline-size;
  width: min(46vh, 78vw);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}

#ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Start at twelve o'clock, run clockwise. */
  transform: rotate(-90deg);
}

#ring circle {
  fill: none;
  stroke-width: 5;
  stroke-linecap: round;
}

.ring__track { stroke: rgba(231, 230, 230, 0.10); }

.ring__fill {
  stroke: #10B981;
  /* 2 * pi * 92, the circumference in the SVG's own units. */
  stroke-dasharray: 578.05;
  stroke-dashoffset: 0;
}

/* The remaining time, inside the ring. Tabular figures keep it from twitching
   as the digits change; the size follows the ring rather than the viewport so
   the two can never collide. */
#clock {
  position: relative;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: clamp(40px, 21cqw, 120px);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.02em;
}

/* The notification status: a button while the choice is still open, a sentence
   once it has been made either way. */
/* Drawn as a card with a bell, because it is the one setting the browser
   version stands or falls with. */
.notice {
  display: grid;
  gap: 10px;
  justify-items: center;
  width: 100%;
  padding: 18px 18px 16px;
  border-radius: 16px;
  background: var(--card);
  border: 1px solid var(--card-border);
}

.notice__icon { color: var(--accent-soft); width: 22px; height: 22px; }
.notice > .guide { border: none; }

.notice .fine:empty { display: none; }

/* MARK: - Break settings

   Folded away: a first-time visitor should meet one decision, not four. */

.settings, .guide {
  width: min(22rem, 100%);
  border: 1px solid rgba(231, 230, 230, 0.14);
  border-radius: 14px;
  text-align: left;
}

.settings__summary, .guide__question {
  padding: 13px 18px;
  cursor: pointer;
  list-style: none;
  font-size: 15px;
  opacity: 0.75;
}

/* Wrench, label, chevron: reads as a button that opens, not as a heading. */
.settings__summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 500;
}

.settings__chevron { width: 16px; height: 16px; opacity: 0.6; transition: transform 160ms; }
details[open] .settings__chevron { transform: rotate(180deg); }

.settings__summary::-webkit-details-marker,
.guide__question::-webkit-details-marker { display: none; }

.guide__question::before {
  content: "＋";
  margin-right: 10px;
  opacity: 0.6;
}

details[open] > .guide__question::before { content: "－"; }

.settings__summary:hover, .guide__question:hover { opacity: 1; }

.settings__body, .guide__body {
  display: grid;
  gap: 10px;
  padding: 4px 18px 20px;
  justify-items: stretch;
}

.settings__label {
  margin: 12px 0 2px;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.45;
}

.settings__schemas { display: grid; gap: 8px; }

.schema {
  display: grid;
  gap: 2px;
  padding: 10px 14px;
  font: inherit;
  text-align: left;
  color: var(--text);
  background: transparent;
  border: 1px solid rgba(231, 230, 230, 0.2);
  border-radius: 10px;
  cursor: pointer;
}

.schema:hover { border-color: rgba(231, 230, 230, 0.45); }

.schema.is-chosen {
  border-color: var(--accent);
  background-color: rgba(1, 147, 223, 0.14);
}

.schema__name { font-size: 15px; }

/* The rhythm in seconds, so the name is not the only thing telling the three
   choices apart. */
.schema__pattern {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  opacity: 0.5;
}

.settings__value {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 22px;
  font-weight: 600;
}

.settings__range { width: 100%; }

.settings__range, #duration, #again-duration {
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  border-radius: 2px;
  background: rgba(231, 230, 230, 0.22);
  cursor: pointer;
}

.settings__range::-webkit-slider-thumb, #duration::-webkit-slider-thumb,
#again-duration::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px; height: 22px;
  border-radius: 50%; border: none;
  background: var(--accent);
}

.settings__range::-moz-range-thumb, #duration::-moz-range-thumb,
#again-duration::-moz-range-thumb {
  width: 22px; height: 22px;
  border-radius: 50%; border: none;
  background: var(--accent);
}

/* MARK: - Notification guide

   Drawn rather than recorded: a screen capture would be one browser at one
   size in one language, and would go stale with the next redesign. */

.guide__steps {
  margin: 4px 0 0;
  padding-left: 20px;
  font-size: 14px;
  line-height: 1.7;
  opacity: 0.75;
}

.guide__svg {
  width: 100%;
  height: auto;
  border-radius: 10px;
  background: rgba(231, 230, 230, 0.04);
  color: var(--text);
}

.guide__bar   { fill: rgba(231, 230, 230, 0.10); }
.guide__url   { fill: rgba(231, 230, 230, 0.22); }
.guide__panel { fill: rgba(231, 230, 230, 0.12); }
.guide__line  { fill: rgba(231, 230, 230, 0.28); }
.guide__line--target { fill: rgba(231, 230, 230, 0.45); }
/* Off until the knob has actually moved. A switch drawn in the "on" colour
   while it is still off tells the opposite of what the guide is teaching. */
.guide__switch { fill: rgba(231, 230, 230, 0.25); }
.guide__knob   { fill: #FFFFFF; }
.guide__cursor { fill: var(--text); }

/* One loop: the pointer travels to the icon, the menu opens, the switch moves.
   Six seconds, because the point is to be followed, not to be caught. */
.guide__menu   { opacity: 0; transform-origin: 24px 52px; }
.guide__knob   { transform: translateX(-18px); }
.guide__cursor { transform: translate(150px, 120px); }

details[open] .guide__menu   { animation: guide-menu 6s ease-in-out infinite; }
details[open] .guide__knob   { animation: guide-knob 6s ease-in-out infinite; }
details[open] .guide__cursor { animation: guide-cursor 6s ease-in-out infinite; }
details[open] .guide__icon   { animation: guide-icon 6s ease-in-out infinite; }
details[open] .guide__switch { animation: guide-switch 6s ease-in-out infinite; }

@keyframes guide-cursor {
  0%, 8%   { transform: translate(150px, 120px); }
  22%, 34% { transform: translate(28px, 28px); }
  52%, 66% { transform: translate(176px, 92px); }
  84%,100% { transform: translate(150px, 120px); }
}

@keyframes guide-icon {
  0%, 18%  { opacity: 0.45; }
  24%, 44% { opacity: 1; }
  56%,100% { opacity: 0.45; }
}

@keyframes guide-menu {
  0%, 26%  { opacity: 0; transform: scale(0.96); }
  34%, 88% { opacity: 1; transform: scale(1); }
  96%,100% { opacity: 0; transform: scale(0.96); }
}

@keyframes guide-knob {
  0%, 62%  { transform: translateX(-18px); }
  70%,100% { transform: translateX(0); }
}

/* Colour turns with the knob, not before it. The reset at the end of the loop
   happens while the menu has already faded out, so it is never seen. */
@keyframes guide-switch {
  0%, 62%  { fill: rgba(231, 230, 230, 0.25); }
  70%,100% { fill: var(--accent); }
}

/* MARK: - Icons

   Line icons in the style of the slides: 24-unit grid, 1.8 stroke, round
   caps. They sit in a tinted round chip when they name a screen, and bare
   inside buttons. */

.icon {
  width: 1.25em;
  height: 1.25em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon--solid { fill: currentColor; stroke: none; }

.chip {
  display: inline-grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  flex: none;
}

.chip .icon { width: 24px; height: 24px; }
.chip--large { width: 64px; height: 64px; }
.chip--large .icon { width: 30px; height: 30px; }

.chip--blue {
  color: var(--accent-soft);
  background: rgba(1, 147, 223, 0.14);
  box-shadow: inset 0 0 0 1px rgba(56, 189, 248, 0.28), 0 0 24px -6px rgba(1, 147, 223, 0.5);
}

.chip--green {
  color: var(--green-soft);
  background: rgba(16, 185, 129, 0.14);
  box-shadow: inset 0 0 0 1px rgba(52, 211, 153, 0.28), 0 0 24px -6px rgba(16, 185, 129, 0.5);
}

/* MARK: - Back to the menu

   A real button, top left, where a back control is looked for — not a link
   in the footer that has to be found. */

.back {
  position: absolute;
  top: 20px;
  left: 20px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px 8px 10px;
  border-radius: 999px;
  border: 1px solid rgba(231, 230, 230, 0.18);
  background: rgba(16, 28, 50, 0.55);
  color: var(--text);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  transition: border-color 160ms, background-color 160ms;
}

.back:hover {
  border-color: rgba(231, 230, 230, 0.45);
  background: rgba(16, 28, 50, 0.85);
}

/* MARK: - Start page */

.entries {
  display: grid;
  gap: 16px;
  width: 100%;
}

@media (min-width: 640px) {
  .entries { grid-template-columns: 1fr 1fr; }
}

/* The two roads, as large cards. Each is the whole target, icon and arrow
   included; hovering lifts it, the way the slide cards glow. */
.entry {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 16px;
  padding: 22px 22px;
  border-radius: 20px;
  background: var(--card);
  border: 1px solid var(--card-border);
  box-shadow: var(--card-lift);
  color: #fff;
  text-decoration: none;
  text-align: left;
  transition: transform 180ms, box-shadow 180ms, border-color 180ms;
}

.entry:hover { transform: translateY(-2px); }
.entry--focus:hover {
  border-color: rgba(56, 189, 248, 0.55);
  box-shadow: 0 0 0 1px rgba(56, 189, 248, 0.2), 0 12px 40px -12px rgba(1, 147, 223, 0.7);
}
.entry--breath:hover {
  border-color: rgba(52, 211, 153, 0.55);
  box-shadow: 0 0 0 1px rgba(52, 211, 153, 0.2), 0 12px 40px -12px rgba(16, 185, 129, 0.7);
}

.entry__title {
  font-family: var(--font-heading);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.3;
}

.entry__arrow { opacity: 0.45; transition: transform 180ms, opacity 180ms; }
.entry:hover .entry__arrow { opacity: 1; transform: translateX(3px); }

/* The Mac app: a card of its own, picture beside text on wide screens. */
/* Deliberately quieter than the two entries above it: no fill, no glow, an
   outlined link instead of a filled button. The page is about the two things
   the web app does; the Mac app is an aside. */
.mac {
  display: grid;
  gap: 16px;
  width: 100%;
  margin-top: 12px;
  padding: 18px 20px;
  border-radius: 16px;
  border: 1px solid rgba(148, 163, 184, 0.12);
  text-align: left;
}

/* The screenshot is portrait; held narrow and to the right of the text so
   the aside stays an aside — on a phone too, a little narrower. */
.mac:has(.mac__shot) { grid-template-columns: 1fr 84px; align-items: center; gap: 16px; }

@media (min-width: 640px) {
  .mac:has(.mac__shot) { grid-template-columns: 1fr 110px; gap: 22px; }
}

.mac__shot { margin: 0; max-width: 130px; order: 2; }

.mac__shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 12px;
  border: 1px solid rgba(148, 163, 184, 0.2);
}

.mac__title {
  margin: 0 0 4px;
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
}

.mac__body { margin: 0 0 12px; font-size: 14px; color: var(--muted); }

.mac__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}


/* The health notice: quiet, but in full and at a size that can actually be
   read — a notice set to be overlooked is not a notice. */
.disclaimer {
  width: 100%;
  text-align: left;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
}

.disclaimer__title {
  margin: 0 0 4px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.disclaimer p { margin: 0; }

/* MARK: - Sound switch */

.switch {
  gap: 12px;
  opacity: 0.85;
}

.switch__track {
  position: relative;
  width: 40px;
  height: 22px;
  border-radius: 999px;
  background: rgba(231, 230, 230, 0.22);
  transition: background-color 160ms;
}

.switch__knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  transition: transform 160ms;
}

.switch[aria-checked="true"] .switch__track { background: var(--green); }
.switch[aria-checked="true"] .switch__knob { transform: translateX(18px); }

/* MARK: - Success

   The end of the exercise gets a mark of its own, in the relief green of the
   breathing circle: a ring that closes, then a tick drawn into it. */

.success svg {
  display: block;
  width: 72px;
  height: 72px;
  fill: none;
  stroke: var(--green-soft);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 18px rgba(16, 185, 129, 0.55));
}

.success circle {
  stroke-dasharray: 132;
  stroke-dashoffset: 132;
  animation: draw 900ms ease-out 150ms forwards;
}

.success path {
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
  animation: draw 500ms ease-out 900ms forwards;
}

@keyframes draw { to { stroke-dashoffset: 0; } }

/* The next block's length on the completion screen: the same control as on
   the setup screen, a size smaller. */
.choice--compact legend { padding-bottom: 4px; }
.choice--compact output {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 20px;
  font-weight: 500;
}
#again-duration { width: min(16rem, 64vw); }

/* MARK: - Utility */

.hidden { display: none !important; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Reduce Motion: the circle holds still and the colour and the tone carry the
   phase. The transitions on the button chrome are dropped with it. */
@media (prefers-reduced-motion: reduce) {
  .button, .entry, .entry__arrow, .switch__track, .switch__knob { transition: none; }
  .success circle, .success path { animation: none; stroke-dashoffset: 0; }

  #screen-done[data-active] .column > * { animation: none; }

  /* The guide's loop is turned off entirely and the menu is simply shown.
     The three written steps carry the instruction on their own — which is why
     they are there and not merely a caption. */
  details[open] .guide__menu,
  details[open] .guide__knob,
  details[open] .guide__cursor,
  details[open] .guide__icon,
  details[open] .guide__switch { animation: none; }

  /* Shown in the state the guide is asking for: menu open, switch on. */
  .guide__menu { opacity: 1; }
  .guide__knob { transform: translateX(0); }
  .guide__switch { fill: var(--accent); }
  .guide__cursor { opacity: 0; }
}
