/* ---------------------------------------------------------------------------
   home.css — AREA: TIMER  (owns js/timer.js, js/audio.js, js/ui/home.js,
                            js/ui/focus.js, css/home.css)

   The home screen, the fullscreen focus screen, and the two sheets home opens
   (the task picker and the white-noise panel). Declares NO custom property:
   every value comes from tokens.css, which is the only file allowed to
   introduce one. A handful of properties ARE read here — --arc-len,
   --gauge-progress, --tile-hue, --bar — but they are written from JS as inline
   styles, which is the same thing effects.css does with --cx/--cy.

   Naming: .home-<block>[__<element>][--<modifier>] and .focus-<block>…, so a
   grep for "home-" or "focus-" finds this area's whole surface.

   Both themes come free through the tokens. There are [data-theme="brutal"]
   overrides below, and every one of them changes a SHAPE — square stroke caps,
   flat ticks, no glow — never a colour.
--------------------------------------------------------------------------- */

/* =========================================================================
   CURRENT TASK PILL
   ========================================================================= */

.home-task {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 68px;
  padding: var(--sp-3) var(--sp-4);
  text-align: start;
  background: var(--c-surface);
  border: var(--card-border);
  border-radius: var(--r-card);
  box-shadow: var(--sh-card);
  color: var(--c-ink);
  transition:
    background var(--d-2) var(--e-out),
    border-color var(--d-2) var(--e-out),
    transform var(--d-1) var(--e-out),
    box-shadow var(--d-1) var(--e-out);
}
.home-task:hover { background: var(--c-surface-2); }
.home-task:active { transform: translate(var(--btn-translate), var(--btn-translate)) scale(0.995); box-shadow: var(--sh-press); }
.home-task.is-empty { border-style: dashed; background: var(--c-surface-2); }

.home-task__icon {
  flex: none;
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  background: var(--tile-hue, var(--c-accent));
  color: #fff;
  border: var(--bw) solid color-mix(in srgb, var(--c-ink) 12%, transparent);
  box-shadow: var(--sh-1);
}
.home-task__icon > svg { width: 22px; height: 22px; }
.home-task.is-empty .home-task__icon {
  background: var(--c-surface);
  color: var(--c-ink-3);
  border: var(--bw) dashed var(--c-line-strong);
  box-shadow: none;
}

.home-task__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.home-task__label { font-size: var(--fs-2xs); font-weight: var(--fw-bold); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--c-ink-3); }
.home-task__title {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-task__meta {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
  font-variant-numeric: tabular-nums;
}
.home-task__meta > svg { width: 13px; height: 13px; }
.home-task__chev { flex: none; color: var(--c-ink-3); transition: transform var(--d-2) var(--e-out); }
.home-task:hover .home-task__chev { transform: translateX(2px); }
[dir="rtl"] .home-task__chev { transform: scaleX(-1); }

/* =========================================================================
   THE GAUGE STAGE
   ========================================================================= */

.home-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-6) var(--sp-4) var(--sp-5);
  overflow: hidden;
}

/* A very soft wash of the phase colour behind the dial. It is a pseudo-element
   so it cannot ever intercept a pointer, and it is the only thing on this
   screen that reacts to the phase with a colour rather than a shape. */
.home-hero::before {
  content: "";
  position: absolute;
  inset: -30% -10% auto;
  height: 70%;
  background: radial-gradient(60% 60% at 50% 40%, var(--c-accent) 0%, transparent 70%);
  opacity: 0.09;
  pointer-events: none;
  transition: opacity var(--d-4) var(--e-out), background var(--d-4) var(--e-out);
}
#app[data-kind="short"] .home-hero::before,
#app[data-kind="long"] .home-hero::before {
  background: radial-gradient(60% 60% at 50% 40%, var(--c-break) 0%, transparent 70%);
}
#app[data-running="true"] .home-hero::before { opacity: 0.16; }
:root[data-theme="brutal"] .home-hero::before { display: none; }

.home-gauge {
  position: relative;
  width: min(288px, 78vw);
  aspect-ratio: 1;
  /* The bottom eighth of the square is the 90° gap in the arc — empty by
     construction. Pulling the transport up into it is what stops the card
     looking like it has a hole in the middle of it. */
  margin-bottom: -8%;
  display: grid;
  place-items: center;
}
.home-gauge__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

.home-gauge__track {
  fill: none;
  stroke: var(--c-track);
  stroke-width: 13;
  stroke-linecap: round;
  stroke-dasharray: 75 100;
}
.home-gauge__arc {
  fill: none;
  stroke: var(--c-accent);
  stroke-width: 13;
  stroke-linecap: round;
  /* pathLength="100" normalises the circle, so 75 units IS the 270° sweep and
     the JS only ever writes a number between 0 and 75. */
  stroke-dasharray: var(--arc-len, 0) 100;
  transition: stroke var(--d-4) var(--e-out);
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--c-accent) 45%, transparent));
}
.home-gauge[data-kind="short"] .home-gauge__arc,
.home-gauge[data-kind="long"] .home-gauge__arc { stroke: var(--c-break); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--c-break) 45%, transparent)); }
.home-gauge[data-kind="long"] .home-gauge__arc { stroke: var(--c-long); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--c-long) 45%, transparent)); }
.home-gauge.is-paused .home-gauge__arc { stroke: var(--c-ink-3); filter: none; }
.home-gauge__arc.is-empty, .focus-dial__arc.is-empty { opacity: 0; }

/* The head of the arc: a small disc that rides the playhead. Positioned by a
   rotation on its group, so it costs one transform write per frame. */
.home-gauge__headwrap { transition: none; }
.home-gauge__head {
  fill: var(--c-surface);
  stroke: var(--c-accent);
  stroke-width: 3.5;
  transition: stroke var(--d-4) var(--e-out), opacity var(--d-2) var(--e-out);
}
.home-gauge[data-kind="short"] .home-gauge__head { stroke: var(--c-break); }
.home-gauge[data-kind="long"] .home-gauge__head { stroke: var(--c-long); }
.home-gauge.is-idle .home-gauge__head { opacity: 0; }
.home-gauge.is-paused .home-gauge__head { stroke: var(--c-ink-3); }

.home-gauge__tick {
  stroke: var(--c-line-strong);
  stroke-width: 1.6;
  stroke-linecap: round;
  opacity: 0.55;
  transition: stroke var(--d-2) var(--e-out), opacity var(--d-2) var(--e-out);
}
.home-gauge__tick--major { stroke-width: 2.4; opacity: 0.8; }
.home-gauge__tick.is-lit { stroke: var(--c-accent); opacity: 1; }
.home-gauge[data-kind="short"] .home-gauge__tick.is-lit { stroke: var(--c-break); }
.home-gauge[data-kind="long"] .home-gauge__tick.is-lit { stroke: var(--c-long); }

.home-gauge__center {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-1);
  text-align: center;
  padding-inline: 18%;
  pointer-events: none;
}
.home-gauge__phase {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-ink-3);
}
.home-gauge__phase > svg { width: 14px; height: 14px; }

.home-gauge__time {
  display: flex;
  align-items: baseline;
  justify-content: center;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-timer);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  line-height: 1.05;
  color: var(--c-ink);
}
/* Each glyph is its own box so a changing digit can be replaced without the
   rest of the number shifting by a hair. */
.home-gauge__digit {
  display: inline-block;
  min-width: 0.62em;
  text-align: center;
  transform-origin: 50% 55%;
}
.home-gauge__digit.is-flip { animation: home-flip var(--d-3) var(--e-out); }
.home-gauge__colon { display: inline-block; width: 0.32em; text-align: center; opacity: 0.55; }

.home-gauge__status {
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  min-height: 1.3em;
}
.home-gauge.is-paused .home-gauge__status { color: var(--c-warn); font-weight: var(--fw-semibold); }

.home-gauge__dots { margin-top: 2px; }
.home-gauge__dots .c-dot { width: 7px; height: 7px; }
/* The block that closes a cycle is wider — the shape of the row says where
   the long break falls without a word of explanation. */
.home-gauge__dots .c-dot--long { width: 15px; border-radius: var(--r-pill); }

@keyframes home-flip {
  0% { transform: translateY(-42%) scaleY(0.62); opacity: 0; }
  55% { transform: translateY(3%) scaleY(1.04); opacity: 1; }
  100% { transform: none; opacity: 1; }
}

/* Breathing while a block runs. Applied to the gauge wrapper, so it moves the
   dial and the number together and never the card around them. */
#app[data-running="true"] .home-gauge.is-running { animation: home-breathe 6s var(--e-in-out) infinite; }
/* The glow is a drop-shadow on the arc, and the breath above scales it: keeping
   both means re-rasterising the filtered SVG every frame for twenty-five
   minutes. It is paid for once at rest and dropped while the block runs — the
   brutal theme already shows the dial reads fine on its stroke colour alone. */
#app[data-running="true"] .home-gauge.is-running .home-gauge__arc { filter: none; }
@keyframes home-breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.018); }
}

:root[data-theme="brutal"] .home-gauge__track,
:root[data-theme="brutal"] .home-gauge__arc { stroke-linecap: butt; }
:root[data-theme="brutal"] .home-gauge__arc { filter: none; }
:root[data-theme="brutal"] .home-gauge__head { fill: var(--c-accent); stroke: var(--c-ink); }
:root[data-theme="brutal"] .home-gauge[data-kind="short"] .home-gauge__head { fill: var(--c-break); }
:root[data-theme="brutal"] .home-gauge[data-kind="long"] .home-gauge__head { fill: var(--c-long); }
:root[data-theme="brutal"] .home-gauge__tick { stroke-linecap: butt; }

/* =========================================================================
   TRANSPORT
   ========================================================================= */

.home-transport {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-5);
}
.home-transport .c-btn--round:not(.home-transport__main) {
  background: var(--c-accent-softer);
  color: var(--c-accent-deep);
  border: var(--bw) solid transparent;
}
.home-transport .c-btn--round:not(.home-transport__main):hover:not(:disabled) { background: var(--c-accent-soft); }
.home-transport .c-btn--round:not(.home-transport__main) > svg { width: 22px; height: 22px; }
/* The satellites carry the phase colour with the primary. A red restart beside
   a green pause reads as two different machines. */
#app[data-kind="short"] .home-transport .c-btn--round:not(.home-transport__main),
#app[data-kind="long"] .home-transport .c-btn--round:not(.home-transport__main) {
  background: color-mix(in srgb, var(--c-break) 14%, transparent);
  color: var(--c-break);
}
#app[data-kind="long"] .home-transport .c-btn--round:not(.home-transport__main) {
  background: color-mix(in srgb, var(--c-long) 14%, transparent);
  color: var(--c-long);
}

.home-transport__main {
  background: var(--c-accent);
  color: var(--c-accent-ink);
  border: var(--bw) solid var(--c-accent-line);
  box-shadow: var(--sh-accent);
}
.home-transport__main:hover:not(:disabled) { background: var(--c-accent-deep); }
.home-transport__main > svg { width: 30px; height: 30px; }
/* The one control that must never be mistaken: while a break runs it wears the
   break colour, so the primary action always tells you which phase you are in. */
#app[data-kind="short"] .home-transport__main,
#app[data-kind="long"] .home-transport__main { background: var(--c-break); border-color: var(--c-break); }
#app[data-kind="long"] .home-transport__main { background: var(--c-long); border-color: var(--c-long); }

.home-transport .c-btn:disabled { opacity: 0.3; }
/* Strict mode dims a control rather than disabling it: pressing it is how the
   rule explains itself, and a dead button explains nothing. */
.home-transport .c-btn.is-locked,
.focus-transport .c-btn.is-locked { opacity: 0.4; }

/* =========================================================================
   QUICK ROW
   ========================================================================= */

.home-quick {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-2);
}
.home-quick__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sp-1);
  min-height: 84px;
  padding: var(--sp-3) var(--sp-1);
  border-radius: var(--r-card);
  border: var(--card-border);
  background: var(--c-surface);
  box-shadow: var(--sh-card);
  color: var(--c-ink-2);
  transition:
    background var(--d-2) var(--e-out),
    color var(--d-2) var(--e-out),
    border-color var(--d-2) var(--e-out),
    transform var(--d-1) var(--e-out),
    box-shadow var(--d-1) var(--e-out);
}
.home-quick__tile:hover { background: var(--c-surface-2); color: var(--c-ink); }
.home-quick__tile:active { transform: translate(var(--btn-translate), var(--btn-translate)) scale(0.97); box-shadow: var(--sh-press); }
.home-quick__tile > svg { width: 22px; height: 22px; flex: none; }
.home-quick__tile[aria-pressed="true"],
.home-quick__tile.is-on {
  background: var(--c-accent-soft);
  border-color: var(--c-accent-line);
  color: var(--c-accent-deep);
}
.home-quick__label {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  line-height: 1.15;
  text-align: center;
  /* Eleven other languages have longer words than "Strict Mode"; two lines is
     the design, not the accident. */
  overflow-wrap: anywhere;
  hyphens: auto;
}
.home-quick__value {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  color: var(--c-accent);
  letter-spacing: var(--ls-normal);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.home-quick__tile[aria-pressed="true"] .home-quick__value { color: inherit; }

/* Three bars that rise while a bed is playing. Pure CSS: the analyser is only
   worth reading where somebody is actually looking at it, which is the sheet. */
.home-meter { display: inline-flex; align-items: flex-end; gap: 2px; height: 10px; }
.home-meter__bar {
  width: 3px;
  height: 40%;
  border-radius: var(--r-pill);
  background: currentColor;
  transform-origin: bottom center;
  animation: home-meter 1.1s var(--e-in-out) infinite;
}
.home-meter__bar:nth-child(2) { animation-delay: 0.18s; height: 100%; }
.home-meter__bar:nth-child(3) { animation-delay: 0.36s; height: 70%; }
@keyframes home-meter {
  0%, 100% { transform: scaleY(0.35); }
  50% { transform: scaleY(1); }
}

/* =========================================================================
   TODAY STRIP
   ========================================================================= */

.home-today { display: flex; flex-direction: column; gap: var(--sp-4); }
.home-today__figures { display: flex; align-items: flex-start; gap: var(--sp-4); }
.home-today__figures > .c-stat { flex: 1 1 0; }
.home-today__streak {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  align-self: flex-start;
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--c-warn-soft);
  color: var(--c-warn);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  white-space: nowrap;
}
.home-today__streak > svg { width: 15px; height: 15px; }
.home-today__streak.is-cold { background: var(--c-surface-sunken); color: var(--c-ink-3); }

.home-goal { display: flex; flex-direction: column; gap: var(--sp-2); }
.home-goal__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); }
.home-goal__label { font-size: var(--fs-sm); color: var(--c-ink-2); font-weight: var(--fw-medium); }
.home-goal__value { font-size: var(--fs-sm); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.home-goal.is-met .home-goal__value { color: var(--c-ok); }
.home-goal.is-met .c-bar__fill { background: var(--c-ok); }

/* =========================================================================
   RECENT TASKS
   ========================================================================= */

.home-recent__play {
  flex: none;
  width: var(--tap); height: var(--tap);
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  background: var(--c-accent-softer);
  color: var(--c-accent);
  border: var(--bw) solid transparent;
  transition: background var(--d-2) var(--e-out), transform var(--d-1) var(--e-spring), color var(--d-2) var(--e-out);
}
.home-recent__play > svg { width: 18px; height: 18px; }
.home-recent__play:hover { background: var(--c-accent); color: var(--c-accent-ink); }
.home-recent__play:active { transform: scale(0.9); }
.home-recent__play.is-current { background: var(--c-accent); color: var(--c-accent-ink); }

.home-recent__bar { width: 100%; margin-top: 6px; height: 4px; }

/* =========================================================================
   TASK PICKER SHEET
   ========================================================================= */

.home-picker { display: flex; flex-direction: column; gap: var(--sp-3); }
.home-picker__list { max-height: min(46vh, 22rem); overflow-y: auto; overscroll-behavior: contain; }
.home-picker__dot { width: 12px; height: 12px; border-radius: var(--r-pill); background: var(--tile-hue, var(--c-accent)); flex: none; }

/* =========================================================================
   WHITE NOISE SHEET
   ========================================================================= */

.home-noise { display: flex; flex-direction: column; gap: var(--sp-4); }

.home-noise__master {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-card);
  background: var(--c-surface-2);
  border: var(--bw) solid var(--c-line);
}
.home-noise__now { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.home-noise__name { font-weight: var(--fw-bold); font-size: var(--fs-md); }

/* The analyser meter. 24 bars, each scaled from JS while the sheet is open —
   one style write per bar per frame, and the whole loop stops on close. */
.home-noise__spectrum {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 34px;
  flex: none;
  width: 96px;
}
.home-noise__spectrum span {
  flex: 1 1 0;
  height: 100%;
  border-radius: var(--r-xs);
  background: var(--c-accent);
  opacity: 0.85;
  transform: scaleY(var(--bar, 0.06));
  transform-origin: bottom center;
  transition: opacity var(--d-3) var(--e-out);
}
/* Silent: a row of low ticks rather than a dotted line pretending to be a
   meter — it should read as "nothing is playing", not as a broken rule. */
.home-noise__spectrum.is-quiet span { opacity: 0.2; transform: scaleY(0.1); }
:root[data-motion="reduced"] .home-noise__spectrum span { transform: scaleY(0.4); }

.home-noise__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-2);
}
.home-noise__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-1);
  min-height: 82px;
  padding: var(--sp-3) var(--sp-1);
  border-radius: var(--r-card);
  border: var(--card-border);
  background: var(--c-surface);
  color: var(--c-ink-2);
  transition: background var(--d-2) var(--e-out), color var(--d-2) var(--e-out),
    border-color var(--d-2) var(--e-out), transform var(--d-1) var(--e-out);
}
.home-noise__tile > svg { width: 22px; height: 22px; }
.home-noise__tile:hover { background: var(--c-surface-2); color: var(--c-ink); }
.home-noise__tile:active { transform: scale(0.97); }
.home-noise__tile[aria-pressed="true"] {
  background: var(--c-accent);
  border-color: var(--c-accent-line);
  color: var(--c-accent-ink);
}
.home-noise__tile[aria-pressed="true"] svg { animation: home-noise-live 3.4s var(--e-in-out) infinite; }
@keyframes home-noise-live {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.12); }
}
.home-noise__tile span {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  text-align: center;
  line-height: 1.15;
  overflow-wrap: anywhere;
}

.home-noise__note { font-size: var(--fs-xs); color: var(--c-ink-3); text-align: center; }

/* =========================================================================
   EMPTY STATE
   ========================================================================= */

.home-empty__art {
  display: grid;
  place-items: center;
  width: 72px; height: 72px;
  margin-inline: auto;
  border-radius: var(--r-pill);
  background: var(--c-accent-softer);
  color: var(--c-accent);
}
.home-empty__art > svg { width: 34px; height: 34px; }

/* =========================================================================
   HEADER BITS OWNED BY HOME
   ========================================================================= */

/* The circle is what you see, the button is what you hit — the avatar stays
   38px and the thumb still gets the full --tap. */
.home-avatar {
  display: grid;
  place-items: center;
  min-width: var(--tap);
  min-height: var(--tap);
  padding: 0; border: 0; background: none; border-radius: var(--r-pill);
}
.home-avatar .c-avatar { width: 38px; height: 38px; font-size: var(--fs-md); }
.home-bell { position: relative; }
.home-bell__dot {
  position: absolute;
  top: 8px; inset-inline-end: 9px;
  width: 9px; height: 9px;
  border-radius: var(--r-pill);
  background: var(--c-accent);
  border: 2px solid var(--c-bg);
}

/* =========================================================================
   RESPONSIVE
   ========================================================================= */

@media (min-width: 600px) {
  .home-gauge { width: min(320px, 62vw); }
  .home-quick__tile { min-height: 92px; }
  .home-quick__label { font-size: var(--fs-xs); }
  .home-noise__grid { grid-template-columns: repeat(4, 1fr); }
}

/* A short viewport — the framed gallery slide on a laptop — gives up the dial
   before it gives up the controls. */
@media (max-height: 640px) and (min-width: 380px) {
  .home-gauge { width: min(220px, 52vw); }
  .home-hero { padding-block: var(--sp-4); gap: var(--sp-3); }
}

/* =========================================================================
   ======================  FULLSCREEN FOCUS  ==============================
   ========================================================================= */

.focus-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(var(--sp-3), 2.5vh, var(--sp-6));
  min-height: 100%;
  padding: calc(var(--sa-t) + var(--sp-5)) max(var(--sp-5), var(--sa-r))
           calc(var(--sa-b) + var(--sp-5)) max(var(--sp-5), var(--sa-l));
  background: var(--c-surface-sunken);
  overflow: hidden;
  text-align: center;
}

/*  THE BACKGROUND, AND WHY THIS ONE.
    A slow radial in the phase colour, sitting behind the dial and breathing on
    an eight-second cycle — roughly a resting breath, which is the pace the
    room is asking for. It is deliberately NOT a moving gradient, a particle
    field or anything with a direction: this screen is propped on a desk in
    peripheral vision for twenty-five minutes at a time, and anything that
    travels across it pulls the eye back every few seconds. A single soft
    swell, at 12% opacity, reads as "the room is alive" from a metre away and
    as nothing at all when you are looking at the page you are working on.
    It also carries the phase: the same shape in green means the break, so the
    state of the session is legible without reading a word.               */
.focus-stage__glow {
  position: absolute;
  inset: -20%;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(closest-side circle at 50% 46%, var(--c-accent) 0%, transparent 72%);
  opacity: 0.12;
  animation: focus-swell 8s var(--e-in-out) infinite;
  will-change: transform, opacity;
}
.focus-stage[data-kind="short"] .focus-stage__glow { background: radial-gradient(closest-side circle at 50% 46%, var(--c-break) 0%, transparent 72%); }
.focus-stage[data-kind="long"] .focus-stage__glow { background: radial-gradient(closest-side circle at 50% 46%, var(--c-long) 0%, transparent 72%); }
.focus-stage.is-idle .focus-stage__glow,
.focus-stage.is-paused .focus-stage__glow { animation: none; opacity: 0.06; }
@keyframes focus-swell {
  0%, 100% { transform: scale(1); opacity: 0.10; }
  50% { transform: scale(1.09); opacity: 0.17; }
}
:root[data-theme="brutal"] .focus-stage__glow { animation: none; opacity: 0.1; background: none; }
:root[data-motion="reduced"] .focus-stage__glow { animation: none; }
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]) .focus-stage__glow { animation: none; }
}

.focus-stage > * { position: relative; z-index: 1; }

.focus-top {
  position: absolute;
  z-index: 2;
  top: calc(var(--sa-t) + var(--sp-2));
  inset-inline: max(var(--sp-3), var(--sa-l)) max(var(--sp-3), var(--sa-r));
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.focus-top__task {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: start;
}
.focus-top__clock {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
  flex: none;
}

.focus-dial {
  position: relative;
  width: min(86vw, 62vh);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}
.focus-dial__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.focus-dial__track { fill: none; stroke: var(--c-line); stroke-width: 5; stroke-linecap: round; stroke-dasharray: 75 100; }
.focus-dial__arc {
  fill: none;
  stroke: var(--c-accent);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: var(--arc-len, 0) 100;
  transition: stroke var(--d-4) var(--e-out);
}
.focus-stage[data-kind="short"] .focus-dial__arc { stroke: var(--c-break); }
.focus-stage[data-kind="long"] .focus-dial__arc { stroke: var(--c-long); }
.focus-stage.is-paused .focus-dial__arc { stroke: var(--c-ink-3); }
.focus-dial__tick { stroke: var(--c-line-strong); stroke-width: 1.4; stroke-linecap: round; opacity: 0.35; }
.focus-dial__tick.is-lit { stroke: var(--c-accent); opacity: 0.9; }
.focus-stage[data-kind="short"] .focus-dial__tick.is-lit { stroke: var(--c-break); }
.focus-stage[data-kind="long"] .focus-dial__tick.is-lit { stroke: var(--c-long); }

.focus-dial__center {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding-inline: 14%;
}
.focus-time {
  display: flex;
  align-items: baseline;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-timer-full);
  font-weight: var(--fw-bold);
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--c-ink);
}
.focus-time .home-gauge__digit { min-width: 0.6em; }
.focus-phase {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-ink-3);
}

.focus-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2) var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
  max-width: 30rem;
}
.focus-meta__item { display: inline-flex; align-items: center; gap: var(--sp-1); }
.focus-meta__item > svg { width: 14px; height: 14px; }

/* The controls retreat rather than disappear: at 12% they are still findable
   in peripheral vision, and any input at all brings them back. */
.focus-chrome {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  transition: opacity var(--d-4) var(--e-out), transform var(--d-4) var(--e-out);
}
.focus-stage.is-dim .focus-chrome { opacity: 0.12; transform: translateY(6px); }
.focus-stage.is-dim .focus-top { opacity: 0.25; }
.focus-top { transition: opacity var(--d-4) var(--e-out); }

/* The hint is the label for the retreated state, so it fades IN as the
   controls fade out. */
.focus-hint {
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
  min-height: 1.2em;
  opacity: 0;
  transition: opacity var(--d-4) var(--e-out);
}
.focus-stage.is-dim .focus-hint { opacity: 0.5; }

.focus-transport { display: flex; align-items: center; justify-content: center; gap: var(--sp-4); }
/* :not() on the satellites, not extra weight on the primary — otherwise the
   satellite colour wins on specificity and the play glyph comes out tinted. */
.focus-transport .c-btn--round:not(.focus-transport__main) {
  background: color-mix(in srgb, var(--c-ink) 8%, transparent);
  color: var(--c-ink-2);
  border: var(--bw) solid transparent;
}
.focus-transport .c-btn--round:not(.focus-transport__main):hover:not(:disabled) { background: color-mix(in srgb, var(--c-ink) 14%, transparent); color: var(--c-ink); }
.focus-transport .c-btn--round[aria-pressed="true"]:not(.focus-transport__main) { color: var(--c-accent); background: var(--c-accent-softer); }
.focus-transport__main {
  background: var(--c-accent);
  color: var(--c-accent-ink);
  border-color: var(--c-accent-line);
  box-shadow: var(--sh-accent);
}
.focus-transport__main:hover:not(:disabled) { background: var(--c-accent-deep); }
.focus-stage[data-kind="short"] .focus-transport__main { background: var(--c-break); border-color: var(--c-break); }
.focus-stage[data-kind="long"] .focus-transport__main { background: var(--c-long); border-color: var(--c-long); }

@media (max-width: 400px) {
  .focus-transport { gap: var(--sp-3); }
}

/* =========================================================================
   REDUCED MOTION
   base.css crushes every duration to 1ms, which is the right answer for a
   transition and the wrong one for a loop: a 1ms infinite animation is a
   strobe. Every looping animation this file introduces is therefore switched
   off by name, and left in a sensible resting pose — the meter bars keep a
   readable height rather than collapsing to a line.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  /* The breath is set by #app[data-running] .home-gauge.is-running; a guard on
     .home-gauge alone loses to it, so this one carries the same weight. */
  :root:not([data-motion="full"]) #app .home-gauge.is-running,
  :root:not([data-motion="full"]) .home-meter__bar,
  :root:not([data-motion="full"]) .home-noise__tile[aria-pressed="true"] svg,
  :root:not([data-motion="full"]) .home-gauge__digit.is-flip { animation: none; }
  :root:not([data-motion="full"]) .home-meter__bar { transform: scaleY(0.7); }
}
:root[data-motion="reduced"] #app .home-gauge.is-running,
:root[data-motion="reduced"] .home-meter__bar,
:root[data-motion="reduced"] .home-noise__tile[aria-pressed="true"] svg,
:root[data-motion="reduced"] .home-gauge__digit.is-flip { animation: none; }
:root[data-motion="reduced"] .home-meter__bar { transform: scaleY(0.7); }
