/* ===================================================================
   wind,oh — lines

   One size of type, everywhere. A serif for words, a mono for live
   figures, a Mincho for the Japanese readout. Color is black at a few
   strengths; red only for recording and for simulated data. Hairlines,
   never boxes. Tight gutters; a 12-column grid.

     header   — one line across the top
     side     — cols 1–3: A wind · B transport · C master · D piece · E about
     stage    — cols 4–12: the lines, then one row per city
   =================================================================== */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
    --paper: #ffffff;
    --ink:   #111111;
    --ink-2: rgba(17, 17, 17, 0.60);   /* 4.6:1 on white: body text that carries meaning */
    --ink-3: rgba(17, 17, 17, 0.46);   /* 3.2:1: labels beside a darker value */
    --rule:  rgba(17, 17, 17, 0.12);
    --rule-2: rgba(17, 17, 17, 0.26);
    --red:   #d2261b;

    --serif: 'Newsreader', 'Iowan Old Style', Palatino, Georgia, serif;
    --mono:  'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
    --jp:    'Hiragino Mincho ProN', 'Yu Mincho', 'Noto Serif JP', 'Noto Serif CJK JP', serif;

    --fs:     clamp(12px, 0.44rem + 0.34vw, 14px);
    --lh:     1.42;
    --gutter: 24px;
    --margin: 28px;
    --row:    calc(var(--fs) * 2.9);
}

html, body { height: 100%; }

body {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--serif);
    font-size: var(--fs);
    line-height: var(--lh);
    font-variation-settings: 'opsz' 12;
    font-feature-settings: 'tnum' 1, 'lnum' 1;
    -webkit-font-smoothing: antialiased;

    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto minmax(0, 1fr);
    column-gap: var(--gutter);
    padding: 0 var(--margin);
    height: 100vh;
    overflow: hidden;
}

h1, h2, p, dl, dd, dt { font: inherit; }
a { color: inherit; text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 0.18em; }
a:hover { text-decoration-color: var(--ink); }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

.mono { font-family: var(--mono); font-size: 0.86em; letter-spacing: -0.01em; }
.jp   { font-family: var(--jp); }
.dim  { color: var(--ink-2); }

/* ── TYPE IN MOTION ─────────────────────────────────────────────
   kugiri splits leaf text into lines / words / chars for a moment and
   reverts when the motion ends. Inline targets are made inline-block so
   a split's line boxes sit inside them, not beside them. Until the intro
   runs the chrome waits, invisible, so nothing flashes unsplit. */

.kg-wait :is(.top, .side, .stage-bar, .cities) { opacity: 0; }
.figure .mono, .c-wind-v, .c-name, .c-ctry, .c-temp, #gv-intensity, .tbtn, .view-btn { display: inline-block; }
[data-char], [data-word] { will-change: transform; }
.fx, .master input, .voice-select, .c-fx, .c-oct, .c-dir, .c-ind, .c-src, .c-num { transition: opacity 0.9s ease 0.9s; }
.kg-wait :is(.fx input, .c-fx, .c-oct, .voice-select) { opacity: 0; }

/* ── LOADER: the wall view, while the page gathers itself ───────── */
.loader {
    position: fixed; inset: 0; z-index: 50;
    background: var(--paper);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0.35em;
    transition: opacity 0.7s ease;
}
.loader canvas { width: min(460px, 76vw); height: 210px; margin-bottom: 1.6em; }
.loader-mark .jp { margin-left: 0.35em; }
.loader-note { color: var(--ink-3); font-style: italic; font-size: 0.9em; }
.loader.done { opacity: 0; pointer-events: none; }

/* ── HEADER ─────────────────────────────────────────────────────── */

.top {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
    align-items: baseline;
    padding: 22px 0 18px;
    border-bottom: 1px solid var(--rule);
}
.brand   { grid-column: 1 / 4; grid-row: 1; white-space: nowrap; }
/* How to use: the one ink item in the family nav, with a circled ? */
.howto-btn {
    grid-column: 4 / 7; grid-row: 2; justify-self: start; margin-top: 0.9em;
    display: inline-flex; align-items: center; gap: 0.45em;
    padding: 0.3em 0.85em 0.26em 0.6em; border: 1px solid var(--ink); border-radius: 999px;
    color: var(--ink); font-size: 0.92em; line-height: 1.2; white-space: nowrap;
    transition: background-color 0.15s, color 0.15s;
}
.howto-btn:hover, .howto-btn[aria-expanded="true"] { background: var(--ink); color: var(--paper); }
.howto-q { width: 1.1em; height: 1.1em; flex: none; }
/* the serif sits high in its line box; drop the word a hair so it centers by eye in the pill */
.howto-label { position: relative; top: 0.08em; }
.howto { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 24px; background: rgba(255,255,255,0.72); opacity: 0; transition: opacity 0.2s; }
.howto.on { opacity: 1; }
.howto[hidden] { display: none; }
.howto-card { width: min(34em, 100%); max-height: calc(100vh - 48px); overflow: auto; background: var(--paper); border: 1px solid var(--ink); padding: 18px 22px 22px; }
.howto-head { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 12px; border-bottom: 1px solid var(--rule); }
.howto-x { color: var(--ink-2); text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 0.18em; }
.howto-x:hover { color: var(--ink); }
.howto-steps { list-style: none; }
.howto-steps li { display: grid; grid-template-columns: 2em 1fr; padding: 12px 0; border-bottom: 1px solid var(--rule); }
.howto-steps li:last-child { border-bottom: 0; padding-bottom: 0; }
.howto-n { font-family: var(--mono); font-size: 0.86em; color: var(--ink-3); padding-top: 0.1em; }
.howto-h { color: var(--ink); }
.howto-p { color: var(--ink-2); margin-top: 0.2em; }

/* a line under Play saying what to do next */
.transport-hint { flex-basis: 100%; color: var(--ink-3); font-style: italic; margin-top: -0.3em; }
.transport-hint[hidden] { display: none; }

.byline  { grid-column: 1 / 4; grid-row: 2; align-self: start; font-size: 0.8em; color: var(--ink-3); margin-top: 0.25em; white-space: nowrap; }
.byline a { color: var(--ink-2); text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 0.2em; }
.byline a:hover { color: var(--ink); text-decoration-color: var(--ink); }
/* a small cloud after the name, like the one on his site; not underlined */
.byline-mark { display: inline-block; margin-left: 0.35em; text-decoration: none; font-family: 'Apple Symbols', 'Segoe UI Symbol', 'Noto Sans Symbols 2', sans-serif; font-size: 1.05em; line-height: 1; transition: transform 0.4s cubic-bezier(.2,.7,.2,1); }
.byline a:hover .byline-mark { transform: translateX(2px) translateY(-1px); }
.family, .tagline, .status { grid-row: 1; }
.brand .jp { margin-left: 0.35em; }
.family  { grid-column: 4 / 6; display: flex; gap: 1.2em; white-space: nowrap; }
.family a { color: var(--ink-3); text-decoration-color: transparent; }
.family a:hover, .family a[aria-current] { color: var(--ink); text-decoration-color: var(--ink); }
.tagline { grid-column: 6 / 9; color: var(--ink-2); }
.status  { grid-column: 9 / 13; display: flex; justify-content: flex-end; gap: 1.6em; white-space: nowrap; }
.status > div { display: flex; gap: 0.5em; align-items: baseline; }
.status dt { color: var(--ink-3); }
.moon-icon { display: inline-flex; align-self: center; margin-right: -0.15em; }
.moon-icon svg { display: block; width: 0.95em; height: 0.95em; }

/* ── SIDE ───────────────────────────────────────────────────────── */

.side {
    grid-column: 1 / 4;
    min-height: 0;
    overflow-y: auto;
    padding: 30px 0 32px;
    scrollbar-width: none;
}
.side::-webkit-scrollbar { display: none; }

.block {
    display: grid;
    grid-template-columns: 8.4em minmax(0, 1fr);
    column-gap: 16px;
    padding: 0 0 30px;
}
.block + .block { padding-top: 14px; border-top: 1px solid var(--rule); }
.label { color: var(--ink); white-space: nowrap; }
.label .key { display: inline-block; width: 1.4em; color: var(--ink-3); }

.figure { white-space: nowrap; }
.figure .mono { font-size: 1em; }

.meta { margin-top: 1.1em; }
.meta > div {
    display: grid;
    grid-template-columns: 3.4em 1fr;
    padding: 0.28em 0;
}
.meta dt { font-family: var(--jp); color: var(--ink-3); font-size: 0.92em; }
.meta dd { font-family: var(--jp); }
.meta dd .mono { font-family: var(--mono); }

.about p + p { margin-top: 0.9em; }
.about .block-body { max-width: 30em; }
.about .keys { color: var(--ink-3); }

/* Text buttons: a word, a small mark, an underline on hover */
.tbtn {
    display: inline-flex;
    align-items: baseline;
    gap: 0.45em;
    padding: 0;
    line-height: var(--lh);
    white-space: nowrap;
    text-decoration: underline;
    text-decoration-color: transparent;
    text-underline-offset: 0.18em;
    transition: text-decoration-color 0.1s;
}
.tbtn:hover { text-decoration-color: var(--ink); }
.tbtn[hidden] { display: none; }

.transport, .util { display: flex; flex-wrap: wrap; align-items: center; column-gap: 1.6em; row-gap: 0.9em; }
.transport { row-gap: 1.5em; }
/* the Play pill is taller than a line of text: lift the row so its words sit on the label's line */
.transport { margin-top: -0.33em; }
.util .tbtn { color: var(--ink-2); }

.stems { color: var(--ink-3); display: inline-flex; gap: 0.35em; align-items: center; cursor: pointer; }
.stems input { accent-color: var(--ink); margin: 0; }
.util-row { flex-basis: 100%; display: flex; gap: 1em; align-items: baseline; }
.place-search { flex-basis: 100%; position: relative; margin-top: 0.2em; }
.place-search input, .util-row input[type="date"] {
    font: inherit; color: var(--ink); background: transparent;
    border: 0; border-bottom: 1px solid var(--rule-2); border-radius: 0;
    padding: 0.2em 0; width: 100%; outline: none;
}
.util-row input[type="date"] { width: auto; color: var(--ink-2); }
.place-search input:focus, .util-row input:focus { border-bottom-color: var(--ink); }
.place-search input::placeholder { color: var(--ink-3); font-style: italic; }
#placeResults {
    list-style: none; position: absolute; left: 0; right: 0; top: 100%; z-index: 5;
    background: var(--paper); border: 1px solid var(--rule); border-top: 0;
}
#placeResults li { padding: 0.35em 0.5em; cursor: pointer; display: flex; justify-content: space-between; gap: 1em; }
#placeResults li span { color: var(--ink-3); }
#placeResults li:hover { background: rgba(17, 17, 17, 0.04); }
.playmode { flex-basis: 100%; display: flex; gap: 1em; align-items: baseline; }
.playmode .midi-row { margin-left: auto; }
.playmode .voice-select { width: auto; color: var(--ink-2); }
.playmode .midi-row[hidden] { display: none; }
.mode-btn { color: var(--ink-3); }
.mode-btn.on { color: var(--ink); text-decoration-color: var(--ink); }
.util .tbtn:hover { color: var(--ink); }

.tbtn--play::before {
    content: '';
    width: 0; height: 0;
    border-left: 0.5em solid currentColor;
    border-top: 0.3em solid transparent;
    border-bottom: 0.3em solid transparent;
}
/* Play is the one outlined control on the page. While the piece is stopped a
   hairline ring breathes out from it, so the way in is easy to find. */
.tbtn--play {
    position: relative;
    padding: 0.4em 0.95em 0.24em 0.8em;    /* more on top than below: the serif's ascent sits high, so this centers the word by eye */
    margin-left: -0.8em;   /* the mark stays on the column edge */
    align-items: center;
    line-height: 1.2;
    border: 1px solid var(--ink);
    border-radius: 999px;
    color: var(--ink);
    text-decoration: none;
    transition: background-color 0.15s, color 0.15s;
}
.tbtn--play:hover { background: var(--ink); color: var(--paper); }
.tbtn--play:not(.is-pause)::after {
    content: '';
    position: absolute; inset: -1px;
    border: 1px solid var(--ink);
    border-radius: inherit;
    pointer-events: none;
    animation: play-breathe 2.6s ease-out infinite;
}
@keyframes play-breathe {
    0%   { transform: scale(1);    opacity: 0.55; }
    70%  { transform: scale(1.18, 1.45); opacity: 0; }
    100% { transform: scale(1.18, 1.45); opacity: 0; }
}
/* Something is chosen and nothing is playing: Play fills with ink and
   pops once, and its ring breathes harder. Hard to miss. */
.tbtn--play.ready { background: var(--ink); color: var(--paper); animation: play-ready 0.55s cubic-bezier(.2,.7,.2,1); }
.tbtn--play.ready:hover { background: #000; }
.tbtn--play.ready::after { animation-duration: 1.5s; border-width: 1.5px; }
@keyframes play-ready { 0% { transform: scale(0.9); } 55% { transform: scale(1.08); } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { .tbtn--play::after { animation: none; opacity: 0; } .tbtn--play.ready { animation: none; } }
.tbtn--play.is-pause::before {
    width: 0.5em; height: 0.55em;
    border: 0;
    border-left: 0.15em solid currentColor;
    border-right: 0.15em solid currentColor;
}
.tbtn--rec { color: var(--ink-2); }
.tbtn--rec::before {
    content: '';
    width: 0.5em; height: 0.5em;
    border-radius: 50%;
    border: 1px solid currentColor;
    transform: translateY(-0.02em);
}
.tbtn--rec:hover { color: var(--red); text-decoration-color: var(--red); }
.tbtn--rec.recording { color: var(--red); }
.tbtn--rec.recording::before { background: currentColor; animation: rec-blink 1.1s ease-in-out infinite; }
@keyframes rec-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

.master { display: flex; flex-direction: column; gap: 0.35em; }

/* Tape's three little knobs, under its slider */
.knobs { cursor: default; margin: 0.15em 0 0.35em; transition: opacity 0.3s; }
.knobs.off { opacity: 0.35; }
.knob-row { display: flex; gap: 1.5em; }
.knob-wrap { display: flex; flex-direction: column; align-items: center; gap: 0.15em; min-width: 2.6em; }
.knob { display: block; width: 22px; height: 22px; cursor: ns-resize; touch-action: none; outline: none; border-radius: 50%; }
.knob svg { display: block; width: 100%; height: 100%; overflow: visible; }
.knob .k-track { fill: none; stroke: var(--rule-2); stroke-width: 1; }
.knob .k-fill  { fill: none; stroke: var(--ink); stroke-width: 1.2; }
.knob .k-hand  { stroke: var(--ink); stroke-width: 1.2; stroke-linecap: round; }
.knob:focus-visible { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px var(--ink-3); }
.knob-label { font-size: 0.8em; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.knob.turning + .knob-label { color: var(--ink); }
.knob-row { gap: 0.4em; justify-content: space-between; min-width: 0; }
.knob-wrap { min-width: 0; flex: 0 1 auto; }

/* the little "i" at the end of each master row */
.info {
    width: 14px; height: 14px; padding: 0; border: 0; background: none;
    color: var(--ink-3); opacity: 0.8; transition: opacity 0.15s, color 0.15s;
}
.info svg { display: block; width: 100%; height: 100%; }
.info:hover, .info:focus-visible, .info[aria-expanded="true"] { opacity: 1; color: var(--ink); outline: none; }
.info-pop {
    position: fixed; z-index: 40; max-width: 19em;
    background: var(--paper); border: 1px solid var(--rule-2);
    padding: 0.7em 0.85em 0.8em; color: var(--ink-2);
    box-shadow: 0 6px 24px rgba(17,17,17,0.06);
}
.info-pop[hidden] { display: none; }
.info-pop .info-title { color: var(--ink); margin-bottom: 0.25em; }
.info-pop dl { display: grid; grid-template-columns: auto 1fr; column-gap: 0.8em; row-gap: 0.35em; margin-top: 0.6em; padding-top: 0.6em; border-top: 1px solid var(--rule); }
.info-pop dt { color: var(--ink); font-style: italic; }
.fx {
    display: grid;
    grid-template-columns: 4.8em 1fr;
    align-items: center;
    column-gap: 14px;
    cursor: pointer;
    color: var(--ink-2);
}

/* ── STAGE ──────────────────────────────────────────────────────── */

.stage {
    grid-column: 4 / 13;
    min-height: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.stage-bar {
    display: flex;
    align-items: baseline;
    gap: 2em;
    padding: 30px 0 0;
}
.stage-bar { justify-content: space-between; }
.tools { display: flex; gap: 1em; flex-shrink: 0; }
.tools .view-btn.on { color: var(--ink); text-decoration-color: var(--ink); }
.stage-caption { padding-top: 0.5em; min-height: 1.4em; }
.stage-caption .dim { color: var(--ink-3); max-width: 62em; }
.views { display: flex; gap: 1.2em; flex-shrink: 0; }
.view-btn {
    padding: 0;
    color: var(--ink-3);
    text-decoration: underline;
    text-decoration-color: transparent;
    text-underline-offset: 0.18em;
}
.view-btn:hover { color: var(--ink); }
.view-btn.on { color: var(--ink); text-decoration-color: var(--ink); }

.stage-canvas {
    position: relative;
    flex: 1 1 auto;
    min-height: 260px;
    margin-top: 10px;
    overflow: hidden;
}
.lines-canvas { position: absolute; inset: 0; display: block; }

.loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-3);
    font-style: italic;
    animation: breathe 2.4s ease-in-out infinite;
    pointer-events: none;
    z-index: 1;
}
.loading[hidden] { display: none; }
@keyframes breathe { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

/* ── CITIES ─────────────────────────────────────────────────────── */

.cities {
    flex: 0 0 auto;
    max-height: 42vh;
    overflow: auto;
    border-top: 1px solid var(--rule);
    margin-top: 8px;
    margin-bottom: 24px;
    scrollbar-width: thin;
    scrollbar-color: var(--rule-2) transparent;
}

.city-grid {
    display: grid;
    grid-template-columns:
        0.9em 1.6em minmax(8em, 1.5fr)      /* ind · num · city */
        4em 1.6em 2.8em 2.2em                /* wind · dir · temp · sun */
        5.6em 2.6em                          /* voice · note */
        repeat(4, minmax(2.8em, 1fr))        /* vol · rev · del · tone */
        4.6em 2.2em;                         /* oct · src */
    column-gap: 16px;
    align-items: center;
}

.city-head {
    position: sticky;
    top: 0;
    z-index: 2;
    height: var(--row);
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    color: var(--ink-3);
    user-select: none;
}
.city-head .h-dir { text-align: center; }

.city-row {
    height: var(--row);
    border-bottom: 1px solid var(--rule);
    cursor: pointer;
    color: var(--ink-2);
    transition: background 0.1s, color 0.1s;
}
.city-row:hover, .city-row.hover { background: rgba(17, 17, 17, 0.028); color: var(--ink); }
.city-row.active { color: var(--ink); }

/* Indicator mirrors the line heads: a ring when playing */
.c-ind { position: relative; height: 1.4em; width: 100%; padding: 0; }
.c-ind:focus-visible { outline: 1px solid var(--ink); outline-offset: 2px; }
.c-ind::before {
    content: '';
    position: absolute;
    left: 0.15em; top: 50%;
    width: 0.3em; height: 0.3em;
    margin-top: -0.15em;
    border-radius: 50%;
    background: var(--ink-3);
}
.city-row.active .c-ind::before {
    left: 0; width: 0.62em; height: 0.62em; margin-top: -0.31em;
    background: var(--paper);
    border: 1px solid var(--ink);
}

.c-num { font-family: var(--mono); font-size: 0.8em; color: var(--ink-3); }

.c-city { display: flex; align-items: baseline; gap: 0.5em; min-width: 0; white-space: nowrap; overflow: hidden; }
.c-name { color: inherit; }
.city-row.active .c-name { font-style: italic; }
.c-ctry { color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; }

.c-wind, .c-temp, .c-note { font-family: var(--mono); font-size: 0.86em; white-space: nowrap; }
.c-wind .c-unit { font-family: var(--serif); font-size: 1.1em; color: var(--ink-3); margin-left: 0.3em; }
.c-dir  { text-align: center; font-variant-emoji: text; }
.c-temp { color: var(--ink-3); }
.c-note { color: var(--ink-3); transition: color 0.8s ease-out; }
.city-row.active .c-note { color: var(--ink); }
.c-note.flash { color: var(--ink); font-weight: 500; transition: none; }

/* the row's tiny sun: a horizon, the day's arc, the night's dip */
.c-sun { display: flex; align-items: center; }
.c-sun svg { width: 28px; height: 16px; overflow: visible; }
.c-sun svg * { fill: none; stroke: currentColor; stroke-width: 1; vector-effect: non-scaling-stroke; }
.c-sun .sg-h { stroke: var(--rule-2); }
.c-sun .sg-day { stroke: var(--ink-3); }
.c-sun .sg-night { stroke: var(--rule-2); stroke-dasharray: 1 2; }
.c-sun .sg-sun { fill: var(--paper); stroke: var(--ink-2); }
.c-sun.night .sg-sun { fill: var(--ink-2); }
.c-sun.night .sg-day { stroke: var(--rule-2); }
.c-sun.night .sg-night { stroke: var(--ink-3); }
.city-row.active .c-sun .sg-sun, .city-row:hover .c-sun .sg-sun { stroke: var(--ink); }
.city-row.active .c-sun.night .sg-sun, .city-row:hover .c-sun.night .sg-sun { fill: var(--ink); }
.city-row.active .c-sun:not(.night) .sg-day { stroke: var(--ink-2); }

.c-src { font-size: 0.86em; color: var(--ink-3); font-style: italic; }
.c-src.sim { color: var(--red); }
.c-src.stale { color: var(--ink-2); }

.voice-select {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    background: transparent;
    border: 0;
    border-radius: 0;
    color: inherit;
    font: inherit;
    padding: 0 1em 0 0;
    cursor: pointer;
    outline: none;
    text-decoration: underline;
    text-decoration-color: var(--rule);
    text-underline-offset: 0.18em;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='4'%3E%3Cpath d='M0 0h7L3.5 4z' fill='%23111' fill-opacity='.4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.2em center;
}
.voice-select:hover, .voice-select:focus-visible { text-decoration-color: var(--ink); }

.c-oct { display: flex; gap: 0.15em; }
.oct-btn {
    min-width: 1.5em;
    padding: 0 0.1em;
    font-family: var(--mono);
    font-size: 0.8em;
    line-height: 1.5;
    color: var(--ink-3);
    border-radius: 1em;
    border: 1px solid transparent;
}
.oct-btn:hover { color: var(--ink); }
.oct-btn.on { color: var(--ink); border-color: var(--rule-2); }

/* ── RANGE INPUTS ───────────────────────────────────────────────── */
/* A hairline; the filled part in ink; a small round thumb. */

input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    --v: 50%;
    width: 100%;
    height: 1.2em;
    margin: 0;
    background: transparent;
    outline: none;
    cursor: pointer;
    border: 0;
}
input[type="range"]::-webkit-slider-runnable-track {
    height: 1px;
    background: linear-gradient(to right, var(--ink) var(--v), var(--rule-2) var(--v));
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 7px; height: 7px;
    margin-top: -3px;
    border-radius: 50%;
    border: 1px solid var(--ink);
    background: var(--paper);
    transition: background 0.08s;
}
input[type="range"]:hover::-webkit-slider-thumb,
input[type="range"]:focus-visible::-webkit-slider-thumb { background: var(--ink); }

input[type="range"]::-moz-range-track { height: 1px; background: var(--rule-2); }
input[type="range"]::-moz-range-progress { height: 1px; background: var(--ink); }
input[type="range"]::-moz-range-thumb {
    width: 6px; height: 6px;
    border-radius: 50%;
    border: 1px solid var(--ink);
    background: var(--paper);
}
input[type="range"]:hover::-moz-range-thumb { background: var(--ink); }

/* ── TOAST ──────────────────────────────────────────────────────── */

.toast {
    position: fixed;
    left: 50%;
    bottom: 20px;
    transform: translateX(-50%);
    background: var(--ink);
    color: var(--paper);
    padding: 0.4em 0.9em;
    border-radius: 2em;
    z-index: 100;
    pointer-events: none;
    white-space: nowrap;
}
.toast[hidden] { display: none; }

/* ── NARROWER ───────────────────────────────────────────────────── */

@media (max-width: 1180px) {
    .side  { grid-column: 1 / 5; }
    .stage { grid-column: 5 / 13; }
    .family { grid-column: 4 / 7; }
    .tagline { display: none; }
    .status { grid-column: 7 / 13; }
    .city-grid {
        grid-template-columns:
            0.9em 1.4em minmax(6em, 1.3fr)
            3.6em 1.4em 2.6em 2.2em
            5.2em 2.4em
            repeat(4, minmax(2.2em, 1fr))
            4.4em 2em;
        column-gap: 8px;
    }
}

@media (max-width: 860px) {
    :root { --margin: 18px; --gutter: 16px; }
    body {
        display: flex;
        flex-direction: column;
        height: auto;
        min-height: 100vh;
        overflow: auto;
        padding: 0 var(--margin) 24px;
    }
    .top { display: flex; flex-wrap: wrap; column-gap: 1em; row-gap: 0.2em; }
    .brand { flex: 1 0 auto; order: 0; }
    .byline { order: 1; flex-basis: 100%; margin-top: 0; }
    .family, .status { order: 2; }
    .howto-btn { order: 2; margin-top: 0.5em; }
    .tagline { display: none; }
    .status { gap: 1em; }
    /* on a phone the side column comes apart: Play sits right under the
       header, above the lines and the cities; the readout and the rest follow */
    .side  { display: contents; }
    .side > .block--transport { order: 1; border-top: 0; padding: 18px 0 20px; }
    .stage { order: 2; }
    .side > .block:not(.block--transport) { order: 3; border-top: 1px solid var(--rule); padding-top: 14px; }
    .side > .block:not(.block--transport):first-child { margin-top: 18px; }
    .about { display: none; }
    .stage-canvas { flex: none; height: 62vw; min-height: 240px; }
    .stage-caption { display: none; }
    .stage-bar { flex-wrap: wrap; row-gap: 0.4em; }
    .tools { gap: 0.8em; }
    .cities { max-height: none; overflow-x: auto; }
    .city-grid { min-width: 760px; }
}

/* Screen-reader only */
.sr-only {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── CHART LABELS (DOM, so kugiri can move them) ──────────────────── */
.label-layer { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.chart-label {
    position: absolute; left: 0; top: 0; white-space: nowrap;
    color: var(--ink-3); line-height: 1; will-change: transform;
}
.chart-label.lit, .chart-label.hover { color: var(--ink); }
.chart-label[hidden] { display: none; }

/* ── READOUT: a figure whose weight is the gust, and a line of kanji
      set vertically, like a scroll ─────────────────────────────────── */
#bigValue { font-family: var(--serif); font-size: 1em; transition: font-variation-settings 0.25s linear; font-variant-numeric: tabular-nums; }
.block-body { position: relative; }
.tategaki {
    position: absolute; right: 0; top: 0;
    writing-mode: vertical-rl;
    font-variation-settings: normal;
    font-family: var(--jp); color: var(--ink-3); letter-spacing: 0.25em;
    line-height: 1.2; height: 16em; white-space: nowrap; overflow: hidden;
    transition: color 0.6s;
}

/* ── LISTEN: the lines alone ──────────────────────────────────────── */
.listen-line, .listen-exit { display: none; }
body.listen .side, body.listen .cities, body.listen .top .tagline, body.listen .top .status { display: none; }
body.listen .stage { grid-column: 1 / -1; }
body.listen .stage-canvas { margin-top: 0; }
body.listen .listen-line {
    display: block; position: absolute; left: 0; bottom: 2px; z-index: 2;
    color: var(--ink-2); pointer-events: none;
}
body.listen .listen-exit { display: inline-flex; position: absolute; right: 0; bottom: 2px; z-index: 2; color: var(--ink-3); }
body.listen .top, body.listen .stage-bar, body.listen .stage-caption, body.listen .listen-exit { transition: opacity 1.2s ease; }
body.listen.listen-idle .top, body.listen.listen-idle .stage-bar, body.listen.listen-idle .stage-caption, body.listen.listen-idle .listen-exit { opacity: 0; }
body.listen.listen-idle { cursor: none; }

/* ── 潮よ: the tide table ─────────────────────────────────────────── */
.tide-grid {
    display: grid;
    grid-template-columns:
        0.9em 1.6em minmax(8em, 1.6fr)
        5em 1.6em 3.6em
        5.6em 2.6em
        minmax(4em, 1fr)
        2.2em;
    column-gap: 16px;
    align-items: center;
}

/* master rows: label · slider · i */
.master { gap: 0.55em; }
.master .fx { grid-template-columns: 4.8em 1fr 14px; column-gap: 20px; }
.master .fx:not(:has(.info)) > input { grid-column: 2 / 4; }
.master .knobs .knob-row { grid-column: 2 / 4; padding-right: 2px; }

/* keep the readout sentence clear of the vertical kanji beside it */
#bigCaption { padding-right: 2em; }
