/* ============================================================
   PICKJAR
   Everything visual. Ported from the Svelte build with the values
   unchanged — see tools/style-probe.js, which compares computed
   styles between the two so drift cannot pass silently.

   Two rules relied on Svelte's scoping and now carry an explicit
   parent: `.kicker` (blue on the resume card, muted in the capture
   field) and the bare `input` / `h1` rules.
   ============================================================ */

/* ---------------------------------------------- FONTS
   Self-hosted; the app has to work offline. Fraunces is subset to
   the seven glyphs in "Pickjar" — it is the wordmark and nothing
   else, so it cannot render any other string. */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/fraunces-wordmark.woff2') format('woff2');
  unicode-range: U+50, U+61, U+63, U+69-6B, U+72;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/schibsted-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: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/schibsted-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/dmmono-400-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: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/dmmono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/dmmono-500-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: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/dmmono-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* ============================================================
   DESIGN TOKENS
   Flat solid fields, tonal families, 1px bevel, hard internal edges.
   Every value here is deliberate — see docs/design-system.md.
   ============================================================ */

:root {
  /* ---- SURFACE ---- */
  --page-from:      #E9EFF3;
  --page-to:        #F2F0EF;
  --page: linear-gradient(135deg, var(--page-from), var(--page-to));

  --panel:          #FFFFFF;   /* panel base, when unfilled       */
  --panel-quiet:    #FCFDFD;   /* list panels, chord sheet        */
  --panel-flat:     #FAFBFC;   /* inert panels e.g. source page   */

  /* ---- BLUE — "ready to play" ----
     Steps 05/06 are decorative only: ~1.05:1 against white, they
     vanish on a dim or sunlit screen. Never the sole carrier. */
  --blue-01:        #D5E5E9;
  --blue-02:        #DAE9ED;
  --blue-03:        #DFECEF;
  --blue-04:        #E4EFF2;
  --blue-05:        #E9F3F5;
  --blue-06:        #F1F7F8;

  /* ---- PEACH — "retune first" ---- */
  --peach-01:       #F5ECDE;
  --peach-02:       #F7EEE2;
  --peach-03:       #FAF2E6;
  --peach-04:       #FCF4EB;
  --peach-05:       #FDF7EF;

  /* ---- INK ---- */
  --ink:            #37424D;
  --ink-muted:      #66737D;
  --ink-label:      #8794A0;
  --ink-on-blue:    #44596A;
  --ink-on-peach:   #6C583B;
  --ink-title-peach:#4E4333;
  --chord:          #456F7C;   /* chord symbols ONLY — reserved   */

  /* ---- STAGE MODE ---- */
  --stage-bg:       #242B32;
  --stage-ink:      #EEF2F5;
  --stage-muted:    #8B99A4;
  --stage-chord:    #A6C6DC;

  /* ---- DEPTH — light from above ---- */
  --bevel-top:      rgba(255,255,255,.75);
  --bevel-bottom:   rgba(90,113,131,.16);
  --hairline:       rgba(90,113,131,.10);
  --drop:           rgba(78,101,119,.13);

  /* ---- RADIUS — rounds the panel only ---- */
  --r-panel:        14px;
  --r-small:        12px;
  --r-pill:         999px;

  /* ---- SPACING — desktop ---- */
  --page-margin:    72px;
  --gutter:         60px;
  --stack:          40px;
  --label-gap:      20px;
  --pad:            32px;

  /* ---- SPACING — mobile, from reference/iphone-home.html ---- */
  --page-margin-sm: 20px;
  --stack-sm:       22px;
  --label-gap-sm:   10px;
  --pad-sm-x:       18px;
  --pad-sm-y:       15px;
  --row-pad-x:      16px;
  --row-pad-y:      11px;
  --spine-w:        12px;
  --rule: rgba(90,113,131,.11);

  /* Tuning not known yet. Colour means tuning, so a row nobody has
     told us about cannot be blue or peach. ink-label at 22% over
     panel-quiet: neutral in hue, close to blue-02 in value. */
  --spine-unset:    #E2E6E9;

  /* ---- TYPE ---- */
  --font-mark: 'Fraunces', Georgia, serif;
  --font-ui:   'Schibsted Grotesk', -apple-system, 'Helvetica Neue', sans-serif;
  --font-mono: 'DM Mono', ui-monospace, Menlo, monospace;

  --mark-weight: 600;
  --mark-axes:   'SOFT' 70, 'WONK' 1;
  --mark-track:  -0.012em;
  --mark-min:    13px;

  --label-size: 9px;
  --label-track: 3px;
  --sheet-size: 14px;

  --label-size-sm:  8.5px;
  --label-track-sm: 2.6px;
  --kicker-size:    8px;
  --kicker-track:   2.2px;
  --row-title:      13.5px;
  --row-sub:        10px;
  --row-key:        11.5px;
  --row-meta:       9.5px;

  /* ---- ALERT ----
     Warning and critical, and nothing else. Peach is a palette colour, not a
     signal, so it must never be hijacked for this.
     A warning *field* is not available in this system: any tint pale enough
     to belong lands 9-13 RGB units from peach-02 and reads as the same
     colour. So the signal carries in ink and weight only.
     7.47:1 on panel-quiet — AAA. */
  --alert:          #8C3A2E;

  /* ---- ICON ---- */
  --icon-pick-tilt: -26deg;
}

/* ============================================================
   BASE
   ============================================================ */

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; min-height: 100%; }

body {
  background: var(--page);
  background-attachment: fixed;
  font-family: var(--font-ui);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

/* ============================================================
   PANEL — the one recipe everything is built from
   Rounded outside, hard inside. overflow:hidden is what clips
   flush segments to the radius, so it is not optional.
   ============================================================ */

.panel {
  background: var(--panel-quiet);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  box-shadow:
    inset 0  1px 0 var(--bevel-top),
    inset 0 -1px 0 var(--bevel-bottom),
    0 2px 5px var(--drop);
  overflow: hidden;
}

/* Segments inside a panel: no gap, no radius, no border. */
.panel > .seg { margin: 0; border: 0; border-radius: 0; }

/* Section header. Lives OUTSIDE the panel, above it. */
.section-label {
  font: var(--label-size-sm) / 1 var(--font-ui);
  letter-spacing: var(--label-track-sm);
  text-transform: uppercase;
  color: var(--ink-label);
  margin: 0 0 var(--label-gap-sm);
}

/* Chord sheet. The one surface with no decoration on it. */
.sheet {
  font: var(--sheet-size)/1.45 var(--font-mono);
  color: var(--ink);
  white-space: pre;
}
.sheet .chord { color: var(--chord); }

/* ============================================================
   FRAME — scroll column, fade, tab bar
   ============================================================ */

.screen { min-height: 100dvh; }

.column {
  max-width: 402px;
  margin: 0 auto;
  /* Standalone on iOS applies a scroll-edge fade to content near the
     top, which caught the wordmark. Clearance on top of the safe area
     pushes it out of that band; in a browser the inset is 0, so the
     mockup's 14px is unchanged. */
  padding: calc(env(safe-area-inset-top, 0px) + 14px) var(--page-margin-sm) 118px;
}

/* The status bar area, in an installed app only.

   iOS paints a band across the top of a standalone web app. Going
   black-translucent removes it: the status bar becomes transparent and the
   page draws underneath. That leaves content sliding up behind the clock, so
   something has to cover it.

   Not a blur. The first attempt used backdrop-filter and it smeared the
   resume card across the top of the screen — a frosted panel is not in this
   design's vocabulary anyway. This is the page's own background instead,
   fixed to the viewport exactly as body's is, so the two gradients line up
   and the strip is invisible against the page. Content simply dissolves into
   the background as it scrolls up.

   Masked at the bottom rather than cut, which mirrors what the app already
   does at the other end: .fade does the same thing above the tab bar.

   display-mode: standalone is the whole point of the guard. In a browser tab
   there is no status bar to sit under, the safe-area inset is 0, and adding
   height here would give the page a forehead for no reason. */
@media (display-mode: standalone) {
  /* Clear the fade before the wordmark starts.
     iOS's effect reaches further down than the safe-area inset does, so
     content that merely clears the status bar still begins inside the fade —
     which is what made the wordmark look like it was sitting underneath it at
     rest. Scrolling *into* the fade is the nice part of the effect and is
     left alone; this is only about where the page starts. Browser tabs keep
     the mockup's 14px, since there is no fade there to clear. */
  .column {
    padding-top: calc(env(safe-area-inset-top, 0px) + 38px);
  }

  body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: calc(env(safe-area-inset-top, 0px) + 10px);
    z-index: 9;
    pointer-events: none;
    background: var(--page);
    background-attachment: fixed;
    -webkit-mask-image: linear-gradient(to bottom, #000 60%, rgba(0, 0, 0, 0));
    mask-image: linear-gradient(to bottom, #000 60%, rgba(0, 0, 0, 0));
  }
}

.fade {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 130px;
  z-index: 7;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(240, 242, 242, 0),
    rgba(240, 242, 242, 0.92)
  );
}

.tabbar {
  position: fixed;
  left: var(--page-margin-sm);
  right: var(--page-margin-sm);
  bottom: max(26px, env(safe-area-inset-bottom, 0px));
  max-width: calc(402px - var(--page-margin-sm) * 2);
  margin: 0 auto;
  height: 56px;
  display: flex;
  background: var(--panel-quiet);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  overflow: hidden;
  box-shadow:
    inset 0 1px 0 var(--bevel-top),
    inset 0 -1px 0 var(--bevel-bottom),
    0 2px 8px var(--drop);
  z-index: 8;
}
.tabbar .tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: var(--ink-label);
  text-decoration: none;
}
.tabbar .on {
  background: var(--blue-05);
  color: var(--ink);
  font-weight: 600;
}

/* ============================================================
   HEAD — wordmark and count
   ============================================================ */

.apphead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 6px 4px 0;
}
.apphead .count { font-size: 11px; color: var(--ink-label); }

/* The leading lockup — the app's only lockup. Pick at 0.65em,
   0.27em gap, tilted -26deg, before the word. */
.wordmark {
  font-family: var(--font-mark);
  font-weight: var(--mark-weight);
  letter-spacing: var(--mark-track);
  line-height: 1;
  color: var(--ink);
  display: inline-flex;
  align-items: baseline;
  white-space: nowrap;
}
.wordmark--sm { letter-spacing: 0; }

/* Explicit width as well as height, always: an <svg> without a width
   defaults to 100% of its container and pads itself out. */
.pick {
  display: inline-block;
  overflow: visible;
  flex: none;
  color: var(--chord);
}
.pick--tilt { transform: rotate(var(--icon-pick-tilt)); }
.wordmark .pick { margin-right: 0.27em; }

/* ============================================================
   SECTIONS
   ============================================================ */

.column section + section { margin-top: var(--stack-sm); }
/* The wordmark needs room before the first section label; at 14px they read
   as one block. */
.column section:first-of-type { margin-top: 28px; }

/* ============================================================
   RESUME CARD — two flush segments, blue-02 over blue-05
   ============================================================ */

/* An anchor now, so it needs the link defaults undone. */
.resume-top {
  padding: 16px var(--pad-sm-x) 14px;
  background: var(--blue-02);
  display: block;
  text-decoration: none;
  color: inherit;
}
.resume-meta { cursor: pointer; }
.resume-top .kicker {
  font-size: var(--kicker-size);
  letter-spacing: var(--kicker-track);
  text-transform: uppercase;
  color: var(--ink-on-blue);
  margin: 0 0 10px;
}
.resume-top h2 {
  font-size: 23px;
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.2px;
  color: var(--ink);
}
.resume-top .by { font-size: 11px; color: var(--ink-on-blue); margin: 2px 0 0; }

.resume-meta {
  background: var(--blue-05);
  padding: 11px var(--pad-sm-x);
  display: flex;
  gap: 16px;
  align-items: center;
  font: 400 var(--row-key) / 1 var(--font-mono);
  color: var(--ink-on-blue);
}
.resume-meta b { color: var(--ink); font-weight: 500; }
.resume-meta .quiet {
  color: var(--ink-on-blue);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.resume-meta .go,
.song-meta .go {
  margin-left: auto;
  flex: none;
  font: 400 11px var(--font-ui);
  color: var(--ink);
  text-decoration: none;
}

/* ============================================================
   CAPTURE — the paste field
   ============================================================ */

/* Input surfaces are peach; the library is blue. Peach is a palette colour
   here, not a signal — it says "this is where you put things in", and it puts
   warmth on every screen whether or not anything needs attention.

   The blue original is kept as `.capture--blue`, and switching back is adding
   that one class in views.js. */
.capture {
  background: var(--peach-05);
  padding: var(--pad-sm-y) var(--pad-sm-x);
  display: flex;
  align-items: center;
  gap: 14px;
}
.capture .field { flex: 1; min-width: 0; }
.capture .kicker {
  display: block;
  font-size: var(--kicker-size);
  letter-spacing: var(--kicker-track);
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 6px;
}
.capture .url {
  display: block;
  width: 100%;
  font: 400 11.5px var(--font-mono);
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
}
.capture .btn { background: var(--peach-02); }
.capture .btn:active:not(:disabled) { background: var(--peach-01); }

/* Variant: the original blue capture field. */
.capture--blue { background: var(--blue-06); }
.capture--blue .btn { background: var(--blue-02); }
.capture--blue .btn:active:not(:disabled) { background: var(--blue-01); }

/* Dimmer than the real value it stands in for — it is an example, not
   something you typed. */
.capture .url::placeholder { color: var(--ink-label); opacity: 0.7; }
.capture .url:focus { outline: none; }

.hint {
  font-size: 10px;
  color: var(--ink-muted);
  margin: 6px 0 0;
  min-height: 1em;
}
.hint.error { color: var(--ink-on-peach); }

/* Round, bevelled, blue-02 — the one place a filled control appears. */
.btn {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--blue-02);
  border: 1px solid var(--hairline);
  box-shadow:
    inset 0 1px 0 var(--bevel-top),
    inset 0 -1px 0 var(--bevel-bottom);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  padding: 0;
}
.btn:disabled { opacity: 0.45; }
.btn:active:not(:disabled) { background: var(--blue-01); }

/* ============================================================
   ROWS — the spine is the tuning signal
   ============================================================ */

/* A row has two destinations — the song, and the source — so it is a
   container rather than one anchor. Nesting anchors is invalid, and making
   the quick action a button would mean opening a window from script, which
   is what browsers pop-up-block. */
.row {
  display: flex;
  align-items: stretch;
  border-top: 1px solid var(--rule);
  position: relative;
}
.row:first-child { border-top: 0; }

.row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: var(--row-pad-y) var(--row-pad-x) var(--row-pad-y) 0;
  text-decoration: none;
  color: inherit;
}
.row-main:active { background: var(--blue-06); }

/* Straight out to the source. Quiet until you look for it. */
.row-open {
  flex: none;
  width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-left: 1px solid var(--rule);
  color: var(--ink-label);
  text-decoration: none;
}
.row-open:active { background: var(--blue-06); color: var(--ink); }

.spine {
  width: var(--spine-w);
  align-self: stretch;
  flex: none;
  background: var(--spine-unset);
}
.spine[data-state='ready'] { background: var(--blue-02); }
.spine[data-state='retune'] { background: var(--peach-02); }

.row .body { min-width: 0; display: flex; flex-direction: column; }
.row .title {
  font-size: var(--row-title);
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row .sub {
  font-size: var(--row-sub);
  color: var(--ink-muted);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row .meta {
  margin-left: auto;
  text-align: right;
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.row .key { font: 500 var(--row-key) / 1 var(--font-mono); color: var(--ink); }
/* A song with no working link. Warm ink, never a peach field: peach means
   "retune first" and colour must keep meaning tuning. This is the same tone
   the app already uses for an error line. */
.row .alert {
	font: 400 var(--row-key) / 1 var(--font-ui);
	color: var(--ink-on-peach);
}
.row .sub--alert { color: var(--ink-on-peach); }

.row .ago {
  font-size: var(--row-meta);
  color: var(--ink-label);
  margin-top: 2px;
  max-width: 96px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================================================
   BANDS — colour on the group header, not every row
   ============================================================ */

.band {
  margin: 0;
  font-size: var(--kicker-size);
  letter-spacing: var(--kicker-track);
  text-transform: uppercase;
  padding: 8px var(--row-pad-x);
}
.band--blue { background: var(--blue-02); color: var(--ink-on-blue); }
.band--peach { background: var(--peach-02); color: var(--ink-on-peach); }
.band--quiet { background: var(--panel-flat); color: var(--ink-label); }

/* ============================================================
   BACKUP
   ============================================================ */

.backup-row { border-top: 1px solid var(--rule); }
.backup-row:first-child { border-top: 0; }
.backup-row button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 13px var(--row-pad-x);
  background: none;
  border: 0;
  font: 400 12px var(--font-ui);
  color: var(--ink);
}
.backup-row button:disabled { color: var(--ink-label); }
.backup-row button:active:not(:disabled) { background: var(--blue-06); }

.status { font-size: 10px; color: var(--ink-muted); margin: var(--label-gap-sm) 4px 0; }
.status.failed { color: var(--ink-on-peach); }

/* ============================================================
   VERSION MARK — quiet, at the foot
   ============================================================ */

.version {
  display: block;
  width: fit-content;
  margin: var(--stack-sm) auto 0;
  padding: 6px 10px;
  font: var(--label-size-sm) / 1 var(--font-mono);
  letter-spacing: var(--label-track-sm);
  color: var(--ink-label);
  text-decoration: none;
}
.version:active { color: var(--ink-muted); }

/* ============================================================
   SONG DETAIL
   ============================================================ */

.back {
  display: inline-block;
  font-size: 11px;
  color: var(--ink-label);
  text-decoration: none;
  padding: 6px 4px 0;
}
.gone { font-size: 13px; color: var(--ink-muted); margin-top: 40px; }

.song-top { padding: 18px var(--pad-sm-x) 16px; background: var(--blue-02); }
.song-top h1 {
  font-size: 23px;
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.2px;
  color: var(--ink);
}
.song-top .by { font-size: 11px; color: var(--ink-on-blue); margin: 2px 0 0; }

.song-meta {
  background: var(--blue-05);
  padding: 11px var(--pad-sm-x);
  display: flex;
  gap: 16px;
  align-items: center;
  font: 400 var(--row-key) / 1 var(--font-mono);
  color: var(--ink-on-blue);
}
.song-meta .quiet {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fact,
.edit {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: var(--row-pad-y) var(--row-pad-x);
  border-top: 1px solid var(--rule);
}
.fact:first-child,
.edit:first-child { border-top: 0; }

.k {
  flex: none;
  width: 52px;
  font-size: var(--row-sub);
  color: var(--ink-label);
  text-transform: uppercase;
  letter-spacing: 1.4px;
}
.v { font-size: var(--row-key); color: var(--ink); min-width: 0; }
.mono { font-family: var(--font-mono); }
.url-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.warn { color: var(--ink-muted); font-size: var(--row-key); }

.edit .field { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.edit .origin {
  font-size: var(--row-meta);
  color: var(--ink-label);
  margin-top: 3px;
}
.edit input {
  width: 100%;
  min-width: 0;
  font: 400 var(--row-title) var(--font-ui);
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: 0;
}
.edit input:focus { outline: none; }
.edit input::placeholder { color: var(--ink-label); }

/* Mono, always. These notes carry chord progressions, and chord
   symbols sit above specific syllables — proportional type destroys
   the alignment. See design-system.md § Type. */
.notes {
  font: var(--sheet-size) / 1.45 var(--font-mono);
  color: var(--ink);
  white-space: pre-wrap;
  padding: var(--row-pad-y) var(--row-pad-x);
  overflow-x: auto;
}
.uncertain {
  margin: 0;
  padding: 0 var(--row-pad-x) var(--row-pad-y);
  font-size: var(--row-meta);
  color: var(--ink-label);
}

.delete {
  width: 100%;
  padding: 13px;
  border-radius: var(--r-panel);
  border: 1px solid var(--hairline);
  background: var(--panel-quiet);
  box-shadow:
    inset 0 1px 0 var(--bevel-top),
    inset 0 -1px 0 var(--bevel-bottom),
    0 2px 5px var(--drop);
  font: 400 12px var(--font-ui);
  color: var(--ink-muted);
}
.delete.confirming { background: var(--peach-02); color: var(--ink-on-peach); }
.cancel {
  display: block;
  margin: 10px auto 0;
  background: none;
  border: 0;
  font: 400 11px var(--font-ui);
  color: var(--ink-label);
}

/* ============================================================
   ADD
   ============================================================ */

.add-url { padding: var(--pad-sm-y) var(--pad-sm-x); background: var(--peach-05); }
.add-url .kicker {
  display: block;
  font-size: var(--kicker-size);
  letter-spacing: var(--kicker-track);
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 6px;
}
.add-field {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: var(--row-pad-y) var(--row-pad-x);
  border-top: 1px solid var(--rule);
}
.add-url input,
.add-field input {
  flex: 1;
  width: 100%;
  min-width: 0;
  font: 400 var(--row-title) var(--font-ui);
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: 0;
}
.add-url input { font: 400 11.5px var(--font-mono); }
.add-url input:focus,
.add-field input:focus { outline: none; }
.add-url input::placeholder,
.add-field input::placeholder { color: var(--ink-label); }

.save {
  display: block;
  width: 100%;
  margin-top: var(--stack-sm);
  padding: 14px;
  border-radius: var(--r-panel);
  border: 1px solid var(--hairline);
  background: var(--blue-02);
  box-shadow:
    inset 0 1px 0 var(--bevel-top),
    inset 0 -1px 0 var(--bevel-bottom),
    0 2px 5px var(--drop);
  font: 600 13px var(--font-ui);
  color: var(--ink);
}
.save:disabled { opacity: 0.45; }
.save:active:not(:disabled) { background: var(--blue-01); }

/* ============================================================
   SEARCH
   ============================================================ */

.search-field { padding: var(--pad-sm-y) var(--pad-sm-x); background: var(--peach-05); }
.search-field input {
  width: 100%;
  font: 400 var(--row-title) var(--font-ui);
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: 0;
  -webkit-appearance: none;
  appearance: none;
}
.search-field input:focus { outline: none; }
.search-field input::placeholder { color: var(--ink-label); }

.empty {
  font-size: 12px;
  color: var(--ink-muted);
  margin: var(--stack-sm) 4px 0;
}

/* ============================================================
   CHANGELOG
   ============================================================ */

.page-title {
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.2px;
  color: var(--ink);
  margin: 10px 4px var(--stack-sm);
}

/* Flush rows inside the panel — no gutters, hairline creases only. */
.note {
  margin: 0;
  padding: var(--row-pad-y) var(--row-pad-x);
  border-top: 1px solid var(--rule);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink);
}
.note:first-child { border-top: 0; }

/* ============================================================
   HOW YOU PLAY IT — the fields that decide the library's shape
   ============================================================ */

/* A value the field could not read. Warm ink, never a peach field: peach
   means "retune first" and colour has to keep meaning tuning. */

.edit--notes { align-items: flex-start; }
.notes-input {
  width: 100%;
  min-width: 0;
  resize: vertical;
  font: var(--sheet-size) / 1.45 var(--font-mono);
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: 0;
}
.notes-input:focus { outline: none; }
.notes-input::placeholder { color: var(--ink-label); font-family: var(--font-ui); }

/* Shortcuts for the tunings that come up, so a hundred songs is not a
   hundred keyboards. Flush under the panel, quiet. */
.quick {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: var(--label-gap-sm) 0 0;
}
.quick-btn {
  padding: 7px 11px;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline);
  background: var(--panel-quiet);
  box-shadow:
    inset 0 1px 0 var(--bevel-top),
    inset 0 -1px 0 var(--bevel-bottom);
  font: 400 11px var(--font-ui);
  color: var(--ink-muted);
}
.quick-btn:active { background: var(--blue-06); color: var(--ink); }

/* A value the field could not use, said next to the field rather than in a
   popup. Warm ink, never a peach field. */
.origin--bad { color: var(--ink-on-peach); }

/* Confirmation for something that just happened, shown once. Quiet — it is a
   receipt, not a warning. */
.notice {
  margin: var(--label-gap-sm) 4px 0;
  font-size: 10px;
  color: var(--ink-muted);
}

/* The relink field reuses the capture panel, whose .url is the input itself.
   Here the input is wrapped, so the wrapper carries the layout. */
.url--static { display: block; width: 100%; }
.url--static input {
  width: 100%;
  font: 400 11.5px var(--font-mono);
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: 0;
}
.url--static input:focus { outline: none; }
.url--static input::placeholder { color: var(--ink-muted); }

/* Songs with no working link. Neutral for now — whether this band should be
   peach is an open question: peach currently means "retune first", and
   whether it can also mean "something is in the way" is a change to the one
   rule the palette rests on. See docs/decisions.md. */
.band--broken { background: var(--panel-flat); color: var(--ink-on-peach); }

/* ============================================================
   READINESS-COLOURED SURFACES
   Blue when the song is playable now, peach when it needs a retune,
   neutral when nobody has said. The same rule the spine follows, applied
   to the surfaces that belong to one song.
   ============================================================ */

/* --- the hero. Two flush segments, one step apart, in whichever family
       the song's tuning calls for. --- */
/* peach-03 over peach-05, not peach-01 over peach-04. Peach-01 is a much
   heavier step than blue-02 is, so the original pairing shouted where the blue
   one murmurs. The stronger step stays on top: light comes from above, and
   putting the darker field underneath would fight every bevel in the system. */
.resume-top[data-state='retune'] { background: var(--peach-03); }
.resume-top[data-state='retune'] .kicker,
.resume-top[data-state='retune'] .by { color: var(--ink-on-peach); }
.resume-top[data-state='retune'] h2 { color: var(--ink-title-peach); }

.resume-meta[data-state='retune'] { background: var(--peach-05); color: var(--ink-on-peach); }
.resume-meta[data-state='retune'] b,
.resume-meta[data-state='retune'] .go { color: var(--ink-title-peach); }

.resume-top[data-state='unknown'] { background: var(--blue-04); }
.resume-meta[data-state='unknown'] { background: var(--blue-06); }

/* --- the song screen. What the app knows stays white; what you fill in
       takes the song's colour, so the editable half is obvious at a
       glance and the tuning rule reaches the detail view too. --- */
.edit[data-state='ready'] { background: var(--blue-06); }
.edit[data-state='retune'] { background: var(--peach-05); }
.edit[data-state='unknown'] { background: var(--panel-flat); }

.song-top[data-state='retune'] { background: var(--peach-03); }
.song-top[data-state='retune'] h1 { color: var(--ink-title-peach); }
.song-top[data-state='retune'] .by { color: var(--ink-on-peach); }
.song-meta[data-state='retune'] { background: var(--peach-05); color: var(--ink-on-peach); }
.song-meta[data-state='retune'] .go { color: var(--ink-title-peach); }
.song-top[data-state='unknown'] { background: var(--blue-04); }
.song-meta[data-state='unknown'] { background: var(--blue-06); }

/* ============================================================
   FLUSH ROWS — layout D
   The whole row carries the tuning instead of a 12px edge. Rejected
   originally for becoming "a quilt at forty", which is true of a long
   ungrouped list and not of a short one or a grouped one — inside a group
   the tint never alternates. So: D for short lists, D' for grouped lists,
   E (spine rows) for anything long and ungrouped.
   ============================================================ */

.row--flush .row-main { padding-left: var(--row-pad-x); }
.row--flush[data-state='ready'] { background: var(--blue-06); }
.row--flush[data-state='retune'] { background: var(--peach-05); }
.row--flush[data-state='unknown'] { background: var(--panel-quiet); }
.row--flush[data-state='broken'] { background: var(--panel-flat); }
.row--flush .row-main:active { background: var(--blue-05); }

/* ============================================================
   ALERT — a state, not a field
   ============================================================ */

/* Layout W3: the second line says what is wrong instead of naming the
   artist, and the right column becomes a verb. Both in alert ink. */
.row .fix {
  font: 600 10px var(--font-ui);
  letter-spacing: 0.6px;
  color: var(--alert);
}
.row .sub--alert { color: var(--alert); }

.origin--bad,
.hint.error,
.status.failed { color: var(--alert); }
.band--broken { background: var(--panel-flat); color: var(--alert); }
.delete.confirming { background: var(--panel-flat); color: var(--alert); }

/* ============================================================
   PAGE HEAD — a title with a control beside it
   ============================================================ */

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.page-head .page-title { margin-bottom: 0; }

/* Quiet until you look for it. Bevelled like every other control here. */
.icon-btn {
  flex: none;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-small);
  border: 1px solid var(--hairline);
  background: var(--panel-quiet);
  box-shadow:
    inset 0 1px 0 var(--bevel-top),
    inset 0 -1px 0 var(--bevel-bottom);
  color: var(--ink-label);
  padding: 0;
}
.icon-btn[aria-pressed='true'] { background: var(--blue-05); color: var(--ink); }
.icon-btn:active { background: var(--blue-06); }

/* A section label with a control on the same line. The label still sits
   outside the panel, above it, as every section label does. */
.list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: var(--stack-sm);
}
.list-head .section-label { margin-bottom: 0; }

/* A refused value says why, under the input where a sentence fits. The label
   turns red with it so the eye lands on the right row first. */
.edit--rejected .k { color: var(--alert); }
.edit--rejected input { color: var(--alert); }
.origin--bad { color: var(--alert); }

/* ============================================================
   CHORDS
   --chord is reserved for chord symbols and the pick. This is the
   first place in the app that spends it on chords.
   ============================================================ */

.chord { color: var(--chord); }

/* The notes field, not being edited. Same metrics as the textarea it swaps
   with, so tapping to edit does not shift a pixel. Monospace, always: chord
   symbols sit above specific syllables and proportional type destroys the
   alignment. */
.notes-view {
  font: var(--sheet-size) / 1.45 var(--font-mono);
  color: var(--ink);
  white-space: pre-wrap;
  min-height: calc(var(--sheet-size) * 1.45 * 4);
  cursor: text;
}
.notes-view--empty { color: var(--ink-label); font-family: var(--font-ui); }

/* Chords found in the notes, listed. Derived, so it is not an input. */
.edit--derived { cursor: default; }
.chord-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  font: 500 var(--row-key) / 1.4 var(--font-mono);
}
