/* Fonts are bundled so the app works offline and visitors' details aren't sent to a font service. Licences are in fonts/. */
@font-face { font-family: "Figtree"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/figtree-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Figtree"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/figtree-latin-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Figtree"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/figtree-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Nunito"; font-style: normal; font-weight: 300; font-display: swap; src: url("fonts/nunito-latin-300-normal.woff2") format("woff2"); }

/* Page basics: safe-area padding keeps content clear of the iPhone notch and home bar. */
/* The status bar and home indicator space is padding inside the body, so the body reaches the screen's edges and nothing,
   such as the player bar's shadow, is cut off in a hard line above the home indicator. */
body { margin: 0; }
img { max-width: 100%; }
[hidden] { display: none !important; }

/* Layout: the breathing scene fills the window; frosted glass controls float over it, with a player bar always in reach. */
:root {
  color-scheme: dark;
  --ink: #ffffff; --soft: rgba(255, 255, 255, .72); --hair: rgba(255, 255, 255, .14);
  --well: rgba(255, 255, 255, .11); --glass: rgba(26, 21, 36, .62); --sheet: rgba(26, 21, 36, .8);
  --on-tint: #17121f; --tint: #ffb27a; --night: #15111d;
  --body: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Figtree", "Segoe UI", system-ui, sans-serif;
  --round: ui-rounded, "SF Pro Rounded", "Nunito", -apple-system, system-ui, sans-serif;
}
*, *::before, *::after { box-sizing: border-box; }
/* The app fills the visible screen. --app-height and --short come from fitScreen in app.js, because iPhone CSS heights can
   include space under Safari's toolbar, or come up one status bar short in the installed app.
   Sheets fixed to the bottom already reach the real bottom there, so they use bottom: 0. Moving them down by --short hid
   their last 62 points off the screen (Lloyd's iPhone, 6 November 2026). The scrim and launch screen still extend by it,
   which is harmless. */
html { height: 100%; height: 100dvh; height: var(--app-height, 100dvh); overflow: hidden; }
body { height: 100%; overflow: hidden; }
body {
  background: var(--night); color: var(--ink); font: 400 16px/1.4 var(--body);
  -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  padding-top: calc(16px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
}
#tide { position: fixed; top: 0; left: 0; width: 100%; height: 100%; height: 100lvh; height: max(var(--app-height, 100lvh), 100lvh); }
.glass {
  background: var(--glass); border: 1px solid var(--hair);
  -webkit-backdrop-filter: blur(30px) saturate(170%); backdrop-filter: blur(30px) saturate(170%);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .glass { background: var(--sheet); } }
.app {
  position: relative; height: 100%; display: grid; gap: 16px;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
}
.app.quiet { grid-template-columns: minmax(0, 1fr); }
.app.quiet .desk { display: none; }
.stage { min-width: 0; min-height: 0; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 12px; }
.top { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
h1 { margin: 0; font: 600 1.0625rem/1.2 var(--body); letter-spacing: -.01em; text-shadow: 0 1px 10px rgba(0, 0, 0, .45); }
.tagline { margin: 2px 0 0; font-size: .875rem; color: var(--ink); text-shadow: 0 1px 10px rgba(0, 0, 0, .6); }
.phase { display: flex; flex-direction: column; gap: 10px; align-items: center; justify-content: center; text-align: center; min-height: 0; }
#word {
  font: 300 clamp(4.5rem, 14vw, 8.5rem)/1 var(--round); letter-spacing: -.02em;
  text-shadow: 0 2px 26px rgba(0, 0, 0, .55);
}
#timing { font-size: .9375rem; font-weight: 500; font-variant-numeric: tabular-nums; padding: 5px 14px; border-radius: 999px; }
.foot { display: grid; gap: 10px; justify-items: center; }
#status { margin: 0; font-size: .9375rem; font-weight: 500; text-align: center; text-shadow: 0 1px 10px rgba(0, 0, 0, .6); }
#status:empty { display: none; }
.done-btn { background: transparent; color: var(--tint); font-weight: 600; min-height: 44px; padding: 0 6px; }

/* Session button under the breathing word, and the drawer it opens. */
.session-btn {
  display: inline-flex; align-items: center; gap: 7px; min-height: 44px; padding: 6px 16px 6px 12px; margin-top: 6px;
  border-radius: 999px; font-size: .9375rem; font-weight: 500; font-variant-numeric: tabular-nums;
}
.session-btn svg { width: 19px; height: 19px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.scrim { position: fixed; inset: 0; bottom: calc(-1 * var(--short, 0px)); z-index: 11; background: rgba(8, 6, 14, .45); opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility .3s; }
.scrim.open { opacity: 1; visibility: visible; }
.drawer {
  position: fixed; z-index: 12; left: 0; right: 0; bottom: 0; max-width: 520px; max-height: 88%; margin-inline: auto;
  display: flex; flex-direction: column; overflow: hidden; border-radius: 28px 28px 0 0;
  background: var(--sheet); border: 1px solid var(--hair); border-bottom: 0; box-shadow: 0 -16px 50px rgba(0, 0, 0, .4);
  -webkit-backdrop-filter: blur(34px) saturate(170%); backdrop-filter: blur(34px) saturate(170%);
  transform: translateY(105%); visibility: hidden; transition: transform .32s cubic-bezier(.2, .9, .3, 1), visibility .32s;
}
.drawer.open { transform: none; visibility: visible; }
.drawer:focus { outline: none; }
.drawer-head {
  display: flex; flex: none; justify-content: space-between; align-items: center; background: #1d1827;
  padding: 10px max(20px, env(safe-area-inset-right, 0px)) 6px max(20px, env(safe-area-inset-left, 0px));
}
.drawer-head h2 { font-size: 1.25rem; }
.drawer-body {
  display: grid; gap: 18px; overflow-y: auto; overscroll-behavior: contain;
  padding: 14px max(20px, env(safe-area-inset-right, 0px)) calc(24px + env(safe-area-inset-bottom, 0px)) max(20px, env(safe-area-inset-left, 0px));
}
.pane { display: grid; gap: 16px; }
/* Timer and Interval tabs, styled like the breathing pattern switch. */
.tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; padding: 3px; border-radius: 14px; background: var(--well); }
.tab { min-height: 44px; border-radius: 11px; background: transparent; font-size: .9375rem; font-weight: 600; color: var(--soft); }
.tab[aria-selected="true"] { background: #fff; color: var(--on-tint); box-shadow: 0 2px 7px rgba(0, 0, 0, .25); }
.update { min-height: 44px; padding: 8px 18px; border-radius: 999px; font-size: .9375rem; font-weight: 500; }
.bar {
  width: 100%; max-width: 580px; border-radius: 30px; padding: 12px 14px;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 14px; align-items: center;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
}
.mix { display: grid; gap: 7px; min-width: 0; }
button { font: inherit; color: inherit; border: 0; cursor: pointer; }
#go {
  width: 64px; height: 64px; border-radius: 50%; background: var(--tint); color: var(--on-tint);
  display: grid; place-items: center; box-shadow: 0 6px 20px rgba(0, 0, 0, .3); transition: transform .16s ease;
}
#go:active { transform: scale(.93); }
#go svg { width: 26px; height: 26px; fill: currentColor; }
#go .stop-icon { display: none; }
#go.playing .play-icon { display: none; }
#go.playing .stop-icon { display: block; }
.round {
  width: 46px; height: 46px; border-radius: 50%; background: var(--well); display: grid; place-items: center;
}
.round svg { width: 21px; height: 21px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
.round[aria-expanded="true"] { background: var(--ink); color: var(--on-tint); }
.row { display: grid; gap: 3px; min-width: 0; }
.row label { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 10px; font-size: .875rem; font-weight: 600; }
output { font-weight: 400; color: var(--soft); white-space: nowrap; font-variant-numeric: tabular-nums; }
input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 26px; margin: 0; background: transparent; cursor: pointer; --v: 50%;
}
input[type=range]::-webkit-slider-runnable-track {
  height: 8px; border-radius: 8px; background: linear-gradient(to right, var(--tint) var(--v), var(--well) var(--v));
}
input[type=range]::-moz-range-track { height: 8px; border-radius: 8px; background: var(--well); }
input[type=range]::-moz-range-progress { height: 8px; border-radius: 8px; background: var(--tint); }
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 24px; height: 24px; margin-top: -8px; border-radius: 50%;
  background: #fff; box-shadow: 0 2px 7px rgba(0, 0, 0, .4);
}
input[type=range]::-moz-range-thumb { width: 24px; height: 24px; border: 0; border-radius: 50%; background: #fff; box-shadow: 0 2px 7px rgba(0, 0, 0, .4); }
input[type=range]:disabled { opacity: .45; }
.desk { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* Only the panels scroll, so the settings header can never move. */
.desk-body { flex: 1; display: flex; flex-direction: column; gap: 12px; min-height: 0; overflow-y: auto; scrollbar-width: none; overscroll-behavior: contain; }
.desk-body::-webkit-scrollbar { display: none; }
.sheet-head { display: none; }
.panel { border-radius: 22px; min-width: 0; flex: none; }
.panel summary {
  list-style: none; cursor: pointer; display: grid; grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 10px; align-items: center; min-height: 58px; padding: 11px 18px; border-radius: 22px;
}
.panel summary::-webkit-details-marker { display: none; }
.panel summary::after {
  content: ""; grid-column: 2; grid-row: 1 / span 2; width: 9px; height: 9px; margin-right: 3px;
  border-right: 2px solid var(--soft); border-bottom: 2px solid var(--soft); transform: rotate(45deg); transition: transform .2s ease;
}
.panel[open] summary::after { transform: rotate(-135deg); }
h2 { margin: 0; font-size: 1.0625rem; font-weight: 600; letter-spacing: -.01em; }
.sum { grid-column: 1; color: var(--soft); font-size: .9375rem; overflow-wrap: anywhere; }
.panel[open] .sum { display: none; }
.panel-body { display: grid; gap: 16px; padding: 2px 18px 18px; min-width: 0; }
fieldset { border: 0; padding: 0; margin: 0; min-width: 0; display: grid; gap: 8px; }
legend { padding: 0; margin-bottom: 8px; font-size: .875rem; font-weight: 600; }
.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chips label { position: relative; cursor: pointer; min-width: 0; }
.chips input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.chips span {
  display: flex; align-items: center; justify-content: center; min-height: 40px; padding: 6px 14px; border-radius: 14px;
  background: var(--well); font-size: .9375rem; font-weight: 500; text-align: center; transition: background .16s ease, color .16s ease;
}
.chips input:checked + span { background: var(--tint); color: var(--on-tint); font-weight: 600; }
.chips.seg { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 2px; padding: 3px; border-radius: 14px; background: var(--well); }
.chips.seg label { display: flex; }
/* Every option fills the switch's full height, so the chosen one stays the same size when another option's label wraps. */
.chips.seg span { flex: 1; background: transparent; min-height: 38px; padding: 5px 6px; border-radius: 11px; font-size: .875rem; }
.chips.seg input:checked + span { background: #fff; box-shadow: 0 2px 7px rgba(0, 0, 0, .25); }
.check { display: flex; gap: 12px; align-items: center; justify-content: space-between; cursor: pointer; font-weight: 500; }
.check small { display: block; color: var(--soft); font-size: .875rem; font-weight: 400; }
.check input {
  -webkit-appearance: none; appearance: none; flex: none; position: relative; margin: 0; width: 51px; height: 31px;
  border-radius: 31px; background: var(--well); cursor: pointer; transition: background .2s ease;
}
.check input::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%;
  background: #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, .35); transition: transform .2s ease;
}
.check input:checked { background: var(--tint); }
.check input:checked::after { transform: translateX(20px); }
.check input:disabled { opacity: .45; }
.note { margin: 0; color: var(--soft); font-size: .875rem; }
.links { margin: 0; display: flex; justify-content: center; gap: 8px; flex: none; }
.links a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; color: var(--soft); font-size: .875rem; font-weight: 500; text-decoration: none; }
.links a:hover, .links a:focus-visible { color: var(--ink); text-decoration: underline; }
/* Classical mix on the main screen: what's playing, with previous, next and repeat-one controls. */
.now {
  width: 100%; max-width: 580px; border-radius: 22px; padding: 6px 8px 6px 16px;
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; gap: 4px; align-items: center;
}
.now-info { margin: 0; display: grid; min-width: 0; font-size: .9375rem; font-weight: 600; }
.now-info > span, .now-info small { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.now-info small { color: var(--soft); font-size: .8125rem; font-weight: 400; font-variant-numeric: tabular-nums; }
#pieceTime:not(:empty) + span::before { content: " · "; }
.now .round { width: 44px; height: 44px; background: transparent; }
.piece { display: grid; gap: 10px; padding: 12px 14px; border-radius: 16px; background: var(--well); }
.round[aria-pressed="true"] { background: var(--tint); color: var(--on-tint); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
:focus-visible, .chips input:focus-visible + span, .file:focus-within { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (max-width: 899px) {
  .app, .app.quiet { grid-template-columns: minmax(0, 1fr); }
  .desk, .app.quiet .desk {
    display: flex; position: fixed; z-index: 5; left: 0; right: 0; bottom: 0; max-width: 620px; margin-inline: auto; max-height: 84%;
    overflow: hidden; border-radius: 28px 28px 0 0; background: var(--sheet); border: 1px solid var(--hair); border-bottom: 0;
    -webkit-backdrop-filter: blur(34px) saturate(170%); backdrop-filter: blur(34px) saturate(170%);
    box-shadow: 0 -16px 50px rgba(0, 0, 0, .4); transition: transform .32s cubic-bezier(.2, .9, .3, 1), visibility .32s;
  }
  .app.quiet .desk { transform: translateY(105%); visibility: hidden; }
  .sheet-head {
    display: flex; flex: none; justify-content: space-between; align-items: center; background: #1d1827;
    padding: 10px max(20px, env(safe-area-inset-right, 0px)) 6px max(20px, env(safe-area-inset-left, 0px));
  }
  .desk-body { padding: 10px max(14px, env(safe-area-inset-right, 0px)) calc(18px + env(safe-area-inset-bottom, 0px)) max(14px, env(safe-area-inset-left, 0px)); }
  .sheet-head h2 { font-size: 1.25rem; }
}
@media (max-height: 640px) { #go { width: 54px; height: 54px; } #word { font-size: 4rem; } }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* Launch screen: the sun rises behind the swell like a breath in, the name settles, then the tagline arrives one word at a time.
   It fades away by itself after about two and a half seconds, and a tap or key press skips it. */
.splash {
  position: fixed; inset: 0; bottom: calc(-1 * var(--short, 0px)); z-index: 20; display: grid; place-items: center; padding: 24px;
  background: radial-gradient(120% 80% at 50% 40%, #2a1238 0%, var(--night) 70%);
  animation: splash-out .5s cubic-bezier(.4, 0, .2, 1) 2.1s forwards;
}
.splash.skip { animation: splash-out .3s ease forwards; }
.splash-mark { display: grid; justify-items: center; text-align: center; animation: splash-drift .5s cubic-bezier(.4, 0, .2, 1) 2.1s forwards; }
.splash.skip .splash-mark { animation: splash-drift .3s ease forwards; }
.splash-art { width: min(52vw, 200px); height: auto; overflow: visible; margin-bottom: 6px; }
.splash-art * { transform-box: fill-box; transform-origin: center; }
.splash-glow { opacity: 0; animation: splash-glow 1.6s cubic-bezier(.2, .8, .2, 1) .1s forwards; }
.splash-sun { transform: translateY(70%); animation: splash-rise 1.2s cubic-bezier(.22, .9, .25, 1) .15s forwards; }
.splash-wave { fill: none; stroke-width: 3.2; stroke-linecap: round; stroke-dasharray: 160; stroke-dashoffset: 160; animation: splash-draw 1s cubic-bezier(.45, 0, .2, 1) .2s forwards; }
.splash-wave.two { stroke-width: 2.6; opacity: .85; animation-delay: .38s; }
.splash-name { margin: 0; font: 300 clamp(2.75rem, 13vw, 4.25rem)/1.05 var(--round); letter-spacing: -.015em; }
.splash-name span {
  display: inline-block; opacity: 0; transform: translateY(.3em); filter: blur(6px);
  animation: splash-letter .8s cubic-bezier(.2, .8, .2, 1) calc(.5s + var(--i) * 45ms) forwards;
}
/* The breathing word waits until the launch screen has gone, so the two don't overlap. */
.phase { transition: opacity .6s ease; }
.launch .phase { opacity: 0; }
/* The negative margin cancels the letter spacing after the last word, so the line stays centred. */
.splash-line { margin: 14px -.26em 0 0; font-size: .8125rem; font-weight: 500; letter-spacing: .26em; text-transform: uppercase; color: #ffb27a; }
.splash-line span { display: inline-block; opacity: 0; transform: translateY(6px); animation: splash-word .6s ease calc(1.05s + var(--i) * .2s) forwards; }
@keyframes splash-glow { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: scale(1); } }
@keyframes splash-rise { to { transform: none; } }
@keyframes splash-draw { to { stroke-dashoffset: 0; } }
@keyframes splash-letter { to { opacity: 1; transform: none; filter: none; } }
@keyframes splash-word { to { opacity: 1; transform: none; } }
@keyframes splash-drift { to { transform: scale(1.04); filter: blur(4px); } }
@keyframes splash-out { to { opacity: 0; visibility: hidden; pointer-events: none; } }
@media (prefers-reduced-motion: reduce) {
  .splash-mark, .splash-mark *, .splash.skip .splash-mark { animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; stroke-dashoffset: 0 !important; }
  .splash-wave.two { opacity: .85 !important; }
}
