/* ==========================================================================
   not too social

   One ground, one ink, and no accent — every theme is monochrome within
   itself, so there is nowhere to put a badge, a status or a metric. Emphasis
   comes from weight, size and a hairline. Never from colour.

   Contrast is the point rather than an afterthought. Text that is too pale to
   read is not restraint, it is decoration pretending to be restraint.

   A theme sets five colours and, for the terminal ones, a face. Nothing else.
   Adding one is those six values and no new rules.
   ========================================================================== */

@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 200 500;
  font-display: swap;
  src: url('/fonts/newsreader-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 200 400;
  font-display: swap;
  src: url('/fonts/newsreader-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---- hangul -------------------------------------------------------------
   Newsreader carries no Hangul, so its unicode-range hands Korean straight to
   the next family in the stack. Left to itself the browser lands on a gothic
   (sans), which reads nothing like the latin beside it. Name a myeongjo
   (serif) for the Hangul blocks instead, and size-adjust it so the two faces
   sit at the same optical size rather than one looking shrunken.
   ------------------------------------------------------------------------ */

@font-face {
  font-family: 'NTS Hangul';
  font-display: swap;
  size-adjust: 108%;
  src: local('AppleMyungjo'), local('Nanum Myeongjo'), local('NanumMyeongjo'),
       local('Noto Serif CJK KR'), local('Noto Serif KR'), local('Source Han Serif K'),
       local('Batang'), local('바탕');
  unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7AF, U+D7B0-D7FF, U+FFA0-FFDC;
}

@font-face {
  font-family: 'NTS Hangul Mono';
  font-display: swap;
  size-adjust: 96%;
  src: local('D2Coding'), local('Apple SD Gothic Neo'), local('Malgun Gothic'),
       local('Noto Sans CJK KR'), local('AppleGothic');
  unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7AF, U+D7B0-D7FF, U+FFA0-FFDC;
}

/* ---- tokens ------------------------------------------------------------ */

:root {
  --paper:  #FAF9F6;   /* the sheet */
  --ink:    #17171A;   /* what you read              — 15.8:1 */
  --ink-2:  #45454A;   /* the app's own quieter voice —  8.6:1 */
  --ink-3:  #6B6B70;   /* hints and labels            —  5.1:1 */
  --rule:   #D9D7D0;   /* hairlines. never text */

  --measure: 34rem;    /* ~64 characters at the reading size */
  --face: 'Newsreader', 'NTS Hangul', Georgia, 'Times New Roman', serif;
  --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas,
          'NTS Hangul Mono', 'Courier New', monospace;
  --tracking: 0;
  --scale: 1;        /* keeps the optical size steady when the face changes */
}

/* ---- the light --------------------------------------------------------
   Every theme sets the same five tokens and nothing else, so a new one is
   five colours and never a new rule. Each keeps its darkest text above 12:1
   and its quietest above 4.5:1 on its own ground — a theme is allowed a
   mood, it is not allowed to be unreadable.

   'night' by system preference, then the reader's explicit choice, which
   must win in both directions. ------------------------------------------ */

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #131315; --ink: #ECEAE4; --ink-2: #B4B2AC; --ink-3: #86847E; --rule: #302F32;
  }
}

/* paper — the default. warm off-white, near-black. */
:root[data-theme='paper'] {
  --paper: #FAF9F6; --ink: #17171A; --ink-2: #45454A; --ink-3: #6B6B70; --rule: #D9D7D0;
}

/* night — the same sheet turned down, not inverted. */
:root[data-theme='night'] {
  --paper: #131315; --ink: #ECEAE4; --ink-2: #B4B2AC; --ink-3: #86847E; --rule: #302F32;
}

/* ink — black and white, no warmth at all. the highest contrast here. */
:root[data-theme='ink'] {
  --paper: #FFFFFF; --ink: #000000; --ink-2: #333333; --ink-3: #595959; --rule: #C9C9C9;
}

/* sepia — old paper, for a long read. */
:root[data-theme='sepia'] {
  --paper: #F3EADA; --ink: #2A2116; --ink-2: #544737; --ink-3: #786854; --rule: #DBCDB4;
}

/* ms-dos — light grey on black, and a monospace face to match. */
:root[data-theme='dos'] {
  --paper: #000000; --ink: #C6C6C6; --ink-2: #9E9E9E; --ink-3: #7E7E7E; --rule: #3A3A3A;
  --face: var(--mono);
  --tracking: 0.01em;
  --scale: 0.9;
}

/* phosphor — a green screen. */
:root[data-theme='phosphor'] {
  --paper: #050F08; --ink: #43F07E; --ink-2: #31C462; --ink-3: #269E4E; --rule: #143D22;
  --face: var(--mono);
  --tracking: 0.01em;
  --scale: 0.9;
}

/* amber — the other terminal. */
:root[data-theme='amber'] {
  --paper: #120C00; --ink: #FFB627; --ink-2: #D2921C; --ink-3: #A87415; --rule: #3B2A06;
  --face: var(--mono);
  --tracking: 0.01em;
  --scale: 0.9;
}

/* ---- ground ------------------------------------------------------------ */

* { box-sizing: border-box; }

html { background: var(--paper); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--face);
  letter-spacing: var(--tracking);
  font-weight: 380;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--rule); color: var(--ink); }

[hidden] { display: none !important; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 5px;
}

/* ---- page frame -------------------------------------------------------- */

.page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 3.5rem 8rem;
}

/* Wordmark and the three acts, together, at the top. */
.mast {
  width: 100%;
  max-width: var(--measure);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.6rem;
  padding: 2.6rem 0 0;
}

.wordmark {
  margin: 0;
  font-size: calc(12px * var(--scale));
  font-weight: 400;
  letter-spacing: 0.3em;
  text-transform: lowercase;
  color: var(--ink-3);
}

.mast nav { display: flex; gap: 2.4rem; }

.mast nav button {
  font-size: calc(14px * var(--scale));
  letter-spacing: 0.16em;
  text-transform: lowercase;
  color: var(--ink-3);
  padding-bottom: 5px;
  border-bottom: 1px solid transparent;
  transition: color 250ms ease, border-color 250ms ease;
}
.mast nav button:hover { color: var(--ink); }
.mast nav button[aria-current='page'] { color: var(--ink); border-bottom-color: var(--ink); }

.stage {
  flex: 1;
  width: 100%;
  max-width: var(--measure);
  transition: opacity 200ms ease;
}
.stage.turning { opacity: 0; }

/* ---- shared voice ------------------------------------------------------ */

.aside {
  font-style: italic;
  font-weight: 380;
  font-size: calc(17px * var(--scale));
  line-height: 1.7;
  color: var(--ink-2);
  margin: 0 0 1rem;
}

.note {
  font-size: calc(15px * var(--scale));
  font-weight: 380;
  line-height: 1.75;
  color: var(--ink-3);
  margin: 1rem 0 0;
}

.hint {
  font-style: italic;
  font-weight: 380;
  font-size: calc(15px * var(--scale));
  color: var(--ink-3);
  margin: 1.8rem 0 0;
}

.centred { text-align: center; animation: fade 900ms ease both; }
.centred .large {
  font-size: calc(21px * var(--scale));
  font-style: italic;
  font-weight: 380;
  line-height: 1.7;
  color: var(--ink);
  margin: 0;
}
.centred .aside { margin: 1rem 0 0; text-align: center; }

#released { margin-top: 28vh; }
#tide-empty, #tide-gone { margin-top: 22vh; }
#tide-waiting { margin-top: 22vh; font-size: calc(18px * var(--scale)); font-style: italic; color: var(--ink-3); }

/* an action, never a button until it is needed */
.act { margin-top: 2.6rem; }

.go {
  font-size: calc(16px * var(--scale));
  font-weight: 400;
  letter-spacing: 0.14em;
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
  padding-bottom: 4px;
  transition: opacity 200ms ease;
}
.go:hover { opacity: 0.55; }

/* ---- currents and exclusions, as words ---------------------------------- */

.words { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.7rem 1.2rem; }

.chip {
  font-size: calc(17px * var(--scale));
  font-weight: 400;
  color: var(--ink);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 3px;
  transition: opacity 200ms ease;
}
.chip:hover { text-decoration: line-through; opacity: 0.5; }

.word-in {
  font-family: inherit;
  font-size: calc(17px * var(--scale));
  font-weight: 380;
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  outline: 0;
  padding: 0 0 3px;
  min-width: 15rem;
  flex: 1;
}
.word-in::placeholder { color: var(--ink-3); font-style: italic; }
.word-in:focus { border-bottom-color: var(--ink); }

/* ---- write ------------------------------------------------------------- */

#view-write { padding-top: 9vh; }

#draft {
  width: 100%;
  min-height: 46vh;
  font-family: inherit;
  font-size: calc(20px * var(--scale));
  font-weight: 380;
  line-height: 1.85;
  color: var(--ink);
  background: transparent;
  border: 0;
  outline: 0;
  resize: none;
  overflow: hidden;
  caret-color: var(--ink);
}
#draft::placeholder { color: var(--ink-3); }

.after { margin-top: 2.6rem; animation: fade 700ms ease both; }

/* The one animation that earns its place. The writing loses its ink from the
   bottom up and drifts, and you watch it go — because you cannot get it back. */
@property --wash {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

.dissolving {
  -webkit-mask-image: linear-gradient(to top, transparent var(--wash), #000 calc(var(--wash) + 16%));
  mask-image: linear-gradient(to top, transparent var(--wash), #000 calc(var(--wash) + 16%));
  animation: washaway 1600ms cubic-bezier(0.4, 0, 0.55, 1) forwards;
  pointer-events: none;
}

@keyframes washaway {
  0%   { --wash: 0%;   opacity: 1; transform: translateY(0); }
  72%  { opacity: 1; }
  100% { --wash: 116%; opacity: 0; transform: translateY(-12px); }
}

@keyframes fade    { from { opacity: 0; } to { opacity: 1; } }
@keyframes surface { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---- read -------------------------------------------------------------- */

#view-read { padding-top: 6vh; }

#tide-piece { animation: surface 1200ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }

#piece-body p {
  font-size: calc(20px * var(--scale));
  font-weight: 380;
  line-height: 1.85;
  margin: 0 0 1.5em;
  text-wrap: pretty;
}

/* A direction, not a person. There is no author, no time and no place here,
   and their absence is the product. */
.piece-current {
  margin: 3rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
  font-size: calc(13px * var(--scale));
  font-weight: 400;
  letter-spacing: 0.12em;
  color: var(--ink-3);
}

/* ---- the current, as a thing you slide ---------------------------------- */

/* A hairline and a mark on it. The scale has named stops and no duration
   anywhere: a current has a feel, not a setting. */
.slider {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  margin: 0.6rem 0 0;
  background: transparent;
  cursor: pointer;
}
.slider::-webkit-slider-runnable-track { height: 1px; background: var(--rule); }
.slider::-moz-range-track { height: 1px; background: var(--rule); }
.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 11px;
  height: 11px;
  margin-top: -5px;
  border-radius: 50%;
  background: var(--ink);
}
.slider::-moz-range-thumb {
  width: 11px;
  height: 11px;
  border: 0;
  border-radius: 50%;
  background: var(--ink);
}
.slider:focus-visible { outline: 0; }
.slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--paper), 0 0 0 4px var(--ink); }
.slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px var(--paper), 0 0 0 4px var(--ink); }

.slider-ends {
  display: flex;
  justify-content: space-between;
  font-size: calc(13px * var(--scale));
  letter-spacing: 0.1em;
  color: var(--ink-3);
  margin-top: 0.7rem;
}

.slider-now { font-size: calc(17px * var(--scale)); color: var(--ink); margin: 1.3rem 0 0; }

/* ---- currents page ----------------------------------------------------- */

#view-dials { padding-top: 9vh; display: flex; flex-direction: column; gap: 3.6rem; }

.choices { display: flex; flex-wrap: wrap; gap: 2rem; }

.choices button {
  font-size: calc(17px * var(--scale));
  color: var(--ink-3);
  padding-bottom: 4px;
  border-bottom: 1px solid transparent;
  transition: color 200ms ease, border-color 200ms ease;
}
.choices button:hover { color: var(--ink); }
.choices button[aria-pressed='true'] { color: var(--ink); border-bottom-color: var(--ink); }

/* ---- narrow screens ---------------------------------------------------- */

@media (max-width: 640px) {
  .page { padding: 0 1.5rem 5rem; }
  #draft, #piece-body p { font-size: calc(18px * var(--scale)); }
  .mast nav { gap: 1.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
