/* =========================================================
   ANALYSER - Swiss / International Typographic Style
   Black on white, hairline rules, 12-col grid, red accent.
   ========================================================= */

/* ---------- VIEW TRANSITIONS ---------- */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.2s;
  animation-timing-function: ease;
}

:root {
  --bg:        #ffffff;
  --fg:        #0a0a0a;
  --muted:     #6b6b6b;
  --hairline:  #0a0a0a;
  --rule:      #e6e6e6;
  --surface:   #f4f4f4;
  --accent:    #e60023;
  --accent-fg: #ffffff;

  --font-sans: "Geist", -apple-system, "Helvetica Neue", Helvetica, "Liberation Sans", system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", "Cascadia Mono", Consolas, "DejaVu Sans Mono", monospace;

  --gap:    24px;
  --pad-x:  clamp(20px, 4vw, 56px);
  --pad-y:  clamp(56px, 9vw, 120px);

  --t-mega:  clamp(64px, 13vw, 200px);
  --t-huge:  clamp(48px, 9vw, 112px);
  --t-h1:    clamp(28px, 4.2vw, 56px);
  --t-h2:    clamp(20px, 2.2vw, 28px);
  --t-h3:    16px;
  --t-body:  16px;
  --t-small: 13px;
  --t-tiny:  11px;
  --t-micro: 10px;

  /* On-dark chrome — theme-independent: these live on always-dark media
     surfaces (spectrogram / waveform / fullscreen) so they do NOT get a dark
     override. */
  --media-bg:              #0a0a0a;
  --on-dark:               #ffffff;
  --surface-on-dark:       #1a1a1a;
  --hairline-on-dark:      #333;
  --hairline-strong:       #555;
  --border-on-dark-ctl:    #444;
  --muted-on-dark:         #999;
  --border-on-dark:        rgba(255, 255, 255, 0.15);
  --border-on-dark-strong: rgba(255, 255, 255, 0.5);

  /* Token triples for alpha tints — use rgb(var(--accent-rgb) / a). */
  --accent-rgb: 230, 0, 35;
  --bg-rgb:     255, 255, 255;

  /* Elevation */
  --shadow-color:   rgba(0, 0, 0, 0.14);
  --shadow-popover: 0 8px 28px var(--shadow-color);

  /* Layout */
  --nav-offset: 60px;
  /* Standalone section dividers echo the navbar's structure - a hairline, a band
     of page-fill, then a hairline - at half the navbar's height (see --nav-offset). */
  --rule-band-h: calc(var(--nav-offset) / 2);
  --radius:     0;

  /* Rhythm */
  --lh-tight: 1.2;
  --lh-body:  1.5;
  --lh-prose: 1.65;
  --ls-caps:  0.08em;
  --ls-micro: 0.15em;
}

* { box-sizing: border-box; }
html { background: var(--bg); }
html, body {
  margin: 0; padding: 0;
  color: var(--fg);
}
body {
  background: transparent;
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.45;
  font-feature-settings: "ss01", "cv11", "tnum";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body::before {
  content: '';
  position: fixed;
  inset: -72px;
  z-index: -1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48'%3E%3Cline x1='0' y1='24' x2='15' y2='24' stroke='%23000' stroke-opacity='0.07' stroke-width='0.75'/%3E%3Cline x1='33' y1='24' x2='48' y2='24' stroke='%23000' stroke-opacity='0.07' stroke-width='0.75'/%3E%3Cline x1='24' y1='0' x2='24' y2='15' stroke='%23000' stroke-opacity='0.07' stroke-width='0.75'/%3E%3Cline x1='24' y1='33' x2='24' y2='48' stroke='%23000' stroke-opacity='0.07' stroke-width='0.75'/%3E%3Cline x1='19' y1='24' x2='29' y2='24' stroke='%23000' stroke-opacity='0.07' stroke-width='0.75'/%3E%3Cline x1='24' y1='19' x2='24' y2='29' stroke='%23000' stroke-opacity='0.07' stroke-width='0.75'/%3E%3C/svg%3E");
  background-size: 72px 72px;
  animation: bg-drift 24s linear infinite;
  will-change: transform;
  pointer-events: none;
}
@keyframes bg-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(72px, 72px, 0); }
}
:root[data-theme="dark"] body::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48'%3E%3Cline x1='0' y1='24' x2='15' y2='24' stroke='%23fff' stroke-opacity='0.12' stroke-width='0.75'/%3E%3Cline x1='33' y1='24' x2='48' y2='24' stroke='%23fff' stroke-opacity='0.12' stroke-width='0.75'/%3E%3Cline x1='24' y1='0' x2='24' y2='15' stroke='%23fff' stroke-opacity='0.12' stroke-width='0.75'/%3E%3Cline x1='24' y1='33' x2='24' y2='48' stroke='%23fff' stroke-opacity='0.12' stroke-width='0.75'/%3E%3Cline x1='19' y1='24' x2='29' y2='24' stroke='%23fff' stroke-opacity='0.12' stroke-width='0.75'/%3E%3Cline x1='24' y1='19' x2='24' y2='29' stroke='%23fff' stroke-opacity='0.12' stroke-width='0.75'/%3E%3C/svg%3E");
}

h1, h2, h3, h4, p, dl, dd, dt { margin: 0; }

a {
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
a:hover { color: var(--accent); }

button { font-family: inherit; }

::selection { background: var(--accent); color: var(--accent-fg); }

/* Keyboard focus — one accent ring on every interactive control. :focus-visible
   fires for keyboard / assistive-tech focus but not mouse clicks, so pointer
   users never see it. Range sliders opt out here and ring their thumb instead. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
select:focus-visible,
input:not([type="range"]):focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- GRID ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gap);
  padding: 0 var(--pad-x);
  max-width: 1440px;
  margin: 0 auto;
  width: 100%;
}

/* On displays wider than the 1440px content column there's empty margin on
   either side, which makes the page edges read as "floating". These two fixed
   hairlines sit at the column's left/right edges and run the full height, from
   the (sticky) navbar down, marking where the site ends. Only rendered once the
   viewport is wider than the content, so narrower screens are unaffected. */
@media (min-width: 1441px) {
  html::before,
  html::after {
    content: '';
    position: fixed;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--hairline);
    z-index: 25;
    pointer-events: none;
  }
  html::before { left: calc(50% - 720px); }
  html::after { right: calc(50% - 720px); }
}

/* ---------- HEADER ---------- */
.site-header {
  padding: clamp(40px, 6vw, 80px) 0 clamp(28px, 4vw, 48px);
  border-bottom: 1px solid var(--hairline);
  max-width: 1440px;
  margin: 0 auto;
}

/* Free-floating section dividers (a hairline with empty space on both sides)
   echo the navbar's structure: a hairline, a strip of page-fill at half the
   navbar height, then a hairline - replacing the old single rules. Applies to
   the home page's numbered sections and the dropzone strip; bars that sit flush
   against another element (the header above the navbar) keep a plain hairline,
   and the changelog's entry rules stay single lines by request. The band is
   drawn as an ::after where the old border-bottom sat. */
.section::after,
.quickdrop::after,
body:has(.patch-page) .site-header::after {
  content: '';
  display: block;
  height: var(--rule-band-h);
  background: var(--bg);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
.section::after { margin-top: var(--pad-y); }
/* The changelog page has no navbar beneath the header, so that header divider is
   free-floating - give it the band. Other pages keep the plain hairline (the
   navbar sits flush against it). */
body:has(.patch-page) .site-header { border-bottom: none; padding-bottom: 0; }
body:has(.patch-page) .site-header::after { margin-top: clamp(28px, 4vw, 48px); }
/* The dropzone strip carries its own horizontal padding, so pull the band back
   out to the full-bleed width the old border-bottom spanned. */
.quickdrop::after {
  margin-top: 24px;
  margin-left: calc(-1 * var(--pad-x));
  margin-right: calc(-1 * var(--pad-x));
}
/* No band where a section sits directly above the footer - the footer keeps its
   own plain top hairline. Restore that section's bottom padding, which the
   band's margin-top would otherwise have supplied. */
.section:last-of-type::after { display: none; }
.section:last-of-type { padding-bottom: var(--pad-y); }

.site-mark {
  grid-column: 1 / span 8;
  -webkit-user-select: none;
  user-select: none;
}
.site-meta {
  grid-column: 10 / span 3;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.site-meta dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 16px;
  margin: 0;
}
.site-meta dt { color: var(--muted); }
.site-meta dd { margin: 0; color: var(--fg); }
.site-meta .dot {
  display: inline-block;
  width: 6px; height: 6px;
  background: var(--accent);
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 4px;
}

.site-kicker {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  display: inline-block;
  margin-bottom: 16px;
}

.site-title {
  font-size: var(--t-mega);
  line-height: 0.86;
  font-weight: 600;
  letter-spacing: -0.045em;
  margin: 0;
}
/* PATCH NOTES PAGE: no left meta rail and no navbar, so the notes column is
   centred. The title uses the normal --t-mega size, like the other pages. */
.patch-page .section .grid { display: block; }
.patch-page .section-content {
  grid-column: auto;
  max-width: 760px;
  margin: 0 auto;
}

/* Byline directly under the title. Its size is a fixed fraction of the title
   size (--t-mega), so the two scale together and the byline's right edge stays
   anchored just left of the "y" at every viewport width. */
.site-byline {
  font-size: calc(var(--t-mega) * 0.29);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  margin: -8px 0 0;
}
.site-byline-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  position: relative;
}
.site-byline-link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  height: 2px;
  width: 0;
  background: currentColor;
  transition: width 0.3s ease;
}
.site-title:hover ~ .site-byline .site-byline-link::after,
.site-byline:hover .site-byline-link::after { width: 100%; }
.site-byline-link:hover::after { background: var(--accent); }

/* CHANGELOG header.
   - "Changelog" is one long word: tighten the tracking and pin it to one row
     (white-space:nowrap) so the per-letter inline-block spans the header effect
     builds can't break between letters and drop the final "g". That break happens
     on wide viewports / zoomed out, where --t-mega clamps at 200px and the word is
     widest in the 8-column header.
   - The title's deep "g" descender dips into the byline, so nudge just the
     "valjdakosta" word down to clear it. position:relative shifts it visually
     without reflowing "Analyser by". Its hover-underline rides 2px beneath it and
     would land on the sub-text below, so reserve the same amount under the byline
     with padding-bottom (padding doesn't margin-collapse, so the sub-text keeps a
     normal gap to the nudged word).
   Both offsets are em of the byline - which scales with --t-mega - so the nudge and
   its clearance track the title as it grows with viewport width. */
.site-mark--changelog .site-title { letter-spacing: -0.09em; white-space: nowrap; }
.site-mark--changelog .site-byline-link {
  position: relative;
  top: 0.37em;
}
.site-mark--changelog .site-byline { padding-bottom: 0.37em; }

.site-sub {
  font-size: clamp(15px, 1.6vw, 18px);
  color: var(--muted);
  margin: 20px 0 0;
  max-width: 50ch;
  line-height: 1.45;
}

/* Cross-page buttons (About / Patch notes) sitting under the header text.
   Outlined mono pills matching the footer nav button; filled when current. */
.site-mark-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 24px 0 0;
}
/* Same look as the old top-right chips (.dark-toggle): small outlined mono
   pill that inverts on hover. */
.header-btn {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 3px 8px;
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--fg);
  text-decoration: none;
}
.header-btn:hover { background: var(--fg); color: var(--bg); }

/* Canonical responsive breakpoints (CSS @media can't read custom properties, so
   these literals ARE the contract): 420px = small phone, 700px = phone, 900px =
   tablet / single-column. Header and sections both collapse at 900px. */
@media (max-width: 900px) {
  .site-mark { grid-column: 1 / -1; }
  .site-byline { margin-top: -4px; }
  .site-meta { grid-column: 1 / -1; margin-top: 24px; }
  .site-meta dl { grid-template-columns: 100px 1fr; }
}

/* ---------- NAV ---------- */
.site-nav {
  position: -webkit-sticky;   /* older iOS Safari needs the prefix to pin */
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--hairline);
  display: grid;
  grid-template-columns: 1fr 1fr 1fr auto;
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--pad-x);
}
/* About page nav is just the 3 section links (Why / Where / What) - no home or
   search chrome - so size it to 3 equal columns instead of the home+links+search
   grid the main page uses. */
body:has(.about-page) .site-nav { grid-template-columns: repeat(3, 1fr); }
.nav-link {
  min-width: 0;
  padding: 16px 4px;
  text-decoration: none;
  color: var(--fg);
  font-size: var(--t-small);
  font-weight: 500;
  border-right: 1px solid var(--rule);
  display: flex;
  align-items: baseline;
  gap: 10px;
  transition: background 0.12s ease, color 0.12s ease;
}
.nav-link:last-of-type { border-right: none; }
.nav-link:hover { background: var(--surface); color: var(--fg); }
.nav-link.is-active { background: var(--fg); color: var(--bg); }
.nav-link.is-active .nav-num { color: var(--bg); opacity: 0.5; }
/* Greyed-out + unresponsive when the link's section isn't on the page (e.g. the
   analysed file isn't photo/audio/video). Home and Search are separate controls. */
.nav-link.is-disabled {
  opacity: 0.35;
  pointer-events: none;
  cursor: default;
}
.nav-link.has-data::after {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
  margin-left: auto;
}
.nav-link.is-active.has-data::after {
  background: var(--bg);
}
.nav-search {
  display: flex;
  align-items: stretch;
  border-left: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
}
.nav-search-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--fg);
  opacity: 0.5;
  height: 46px;
  transition: opacity 0.15s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  width: 46px;
}
.nav-search-btn:hover { opacity: 1; }
.nav-search.is-open .nav-search-btn { display: none; }
.nav-search-input {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--hairline);
  border-radius: 0;
  outline: none;
  display: none;
}
.nav-search.is-open .nav-search-input {
  display: block;
  width: 180px;
  padding: 6px 10px;
  opacity: 1;
}
.nav-search-input:focus { border-color: var(--accent); }
.nav-search-input::placeholder {
  color: var(--muted);
  opacity: 0.4;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 11px;
}
.nav-search-arrow { display: none; }
.nav-search.is-open .nav-search-arrow {
  display: block;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--fg);
  font-size: 18px;
  line-height: 1;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.5;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.nav-search.is-open .nav-search-arrow:hover { opacity: 1; background: var(--surface); }
.nav-search.is-open .nav-search-arrow:active { opacity: 1; background: var(--fg); color: var(--bg); }
.nav-search-arrow:hover { opacity: 1; }
.search-overlay { display: none; }
@media (max-width: 700px) {
  .search-overlay {
    display: block;
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
    background: var(--bg);
    border-bottom: 1px solid var(--hairline);
    padding: 10px 16px;
    opacity: 0;
    transform: translateY(-100%);
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease;
  }
  .search-overlay.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }
}
.search-overlay-bar {
  display: flex;
  align-items: center;
  gap: 10px;
}
.search-overlay-input {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 10px 12px;
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--hairline);
  border-radius: 0;
  outline: none;
}
.search-overlay-input:focus { border-color: var(--accent); }
.search-overlay-input::placeholder {
  color: var(--muted);
  opacity: 0.4;
  text-transform: uppercase;
}
.search-overlay-close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--fg);
  font-size: 24px;
  line-height: 1;
  padding: 6px;
  opacity: 0.5;
}
.search-overlay-close:hover { opacity: 1; }
.search-overlay-arrow {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--fg);
  font-size: 28px;
  line-height: 1;
  padding: 0;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.5;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.search-overlay-arrow:hover { opacity: 1; background: var(--surface); }
.search-overlay-arrow:active { opacity: 1; background: var(--fg); color: var(--bg); }
.anr-search-highlight {
  background: rgba(var(--accent-rgb), 0.06);
}
.anr-search-current {
  background: rgba(var(--accent-rgb), 0.15);
}
.nav-num {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  letter-spacing: 0.08em;
}

/* ---------- SECTIONS ---------- */
.section {
  padding: var(--pad-y) 0 0;
  scroll-margin-top: var(--nav-offset);
  max-width: 1440px;
  margin: 0 auto;
}
.section-meta {
  grid-column: 1 / span 3;
  align-self: start;
  /* Pin the number + kicker to the left while its section scrolls past. The
     containing block is the grid, so it stays put until the section ends, then
     scrolls away with it. Reset to static on mobile (see ≤900px override). */
  position: sticky;
  top: calc(var(--nav-offset) + 16px);
  padding-top: 4px;
  background: var(--bg);
  padding: 24px;
  border: 1px solid var(--hairline);
}
.section-num {
  font-family: var(--font-mono);
  font-size: var(--t-huge);
  font-weight: 500;
  line-height: 0.9;
  letter-spacing: -0.03em;
  display: block;
}
.section-kicker {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 12px;
  display: block;
}
.section-content {
  grid-column: 5 / -1;
  background: var(--bg);
  padding: 32px;
  border: 1px solid var(--hairline);
}
.section-head {
  font-size: var(--t-h1);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.05;
  margin: 0 0 16px;
  max-width: 22ch;
}
/* Section headings react to hover (the per-letter weight effect), so show the
   normal arrow cursor rather than the text I-beam - on the elements AND on the
   per-letter <span>s the hover effect injects (so the I-beam never shows over the
   glyphs). user-select:none also keeps a stray drag from selecting the text. The
   .is-tappable pointer rule below is more specific, so mobile tap still wins. */
.section-num, .section-kicker, .section-head,
.section-num span, .section-kicker span, .section-head span {
  cursor: default;
  -webkit-user-select: none;
  user-select: none;
}
.section-lede {
  font-size: clamp(14px, 1.4vw, 17px);
  color: var(--muted);
  max-width: 60ch;
  margin: 0 0 32px;
}

/* Heading mirrored into the numbered meta card (clone created in app.js). Hidden
   by default; on mobile, once the section has analysed a file (.is-analysed), it
   replaces the original head + lede so the results lead. Desktop keeps the full
   head + lede and never shows this clone. */
.section-meta-head { display: none; }
.section.is-tappable .section-head,
.section.is-tappable .section-lede,
.section.is-tappable .section-meta-head { cursor: pointer; }
@media (max-width: 700px) {
  .section.is-analysed .section-head,
  .section.is-analysed .section-lede { display: none; }
  .section.is-analysed .section-meta {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: baseline;
    gap: 0 10px;
  }
  .section.is-analysed .section-num { grid-column: 1; grid-row: 1; }
  .section.is-analysed .section-meta-head {
    display: block;
    grid-column: 2;
    grid-row: 1;
    margin: 0;
    font-size: var(--t-small);
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--fg);
  }
  .section.is-analysed .section-kicker {
    grid-column: 1 / -1;
    grid-row: 2;
  }
  .section.is-analysed .section-meta-slot { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
  .section-meta { grid-column: 1 / -1; position: static; margin-bottom: 8px; }
  .section-content { grid-column: 1 / -1; }
  .section-num { font-size: clamp(40px, 14vw, 80px); }
}

/* ---------- DROPZONE ---------- */
.anr-dropzone {
  border: 1px solid var(--hairline);
  background: var(--bg);
  margin: 24px 0 32px;
  transition: background 0.12s ease, border-color 0.2s ease;
}
.anr-dropzone:hover {
  border-color: var(--accent);
}
.anr-dropzone-inner {
  transition: opacity 0.15s ease;
}
.anr-dropzone:hover .anr-dropzone-inner {
  opacity: 0.6;
}
/* Hovering the dropzone tints its whole outer border accent (above). The
   buttons inside draw their own inner borders (Info's top/left, the audio
   strip's top, the Record/Live divider), so tint those to match - otherwise the
   card edge goes red while the button edges stay dark. */
.anr-dropzone:hover .fmt-help-btn {
  border-top-color: var(--accent);
  border-left-color: var(--accent);
}
.anr-dropzone:hover .anr-audio-modes { border-top-color: var(--accent); }
.anr-dropzone:hover .anr-audio-modes .anr-btn { border-right-color: var(--accent); }
.anr-dropzone.is-dragover {
  background: var(--surface);
  outline: 2px dashed var(--accent);
  outline-offset: -8px;
}
.anr-dropzone-inner {
  display: block;
  padding: clamp(40px, 8vw, 88px) 24px;
  text-align: center;
  cursor: pointer;
}
.anr-drop-icon {
  font-family: var(--font-mono);
  font-size: clamp(28px, 5vw, 44px);
  font-weight: 300;
  display: inline-block;
  margin-bottom: 10px;
}
.anr-dropzone-inner strong {
  display: block;
  font-size: var(--t-h2);
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 4px 0 6px;
}
.anr-dropzone-inner p {
  margin: 6px 0;
  color: var(--muted);
}
.anr-pick-link {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  font-weight: 500;
}
.anr-hint {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  margin-top: 14px !important;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
}
/* The "analysis may be limited" caveat. Styled like a hint but kept on its own
   class so it survives the mobile rule that hides the format-list hints. */
.anr-drop-warn {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  opacity: 0.5;
  margin-top: 14px !important;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  overflow-wrap: anywhere;
}
.quickdrop-zone .anr-drop-warn { margin-top: 10px !important; }

.anr-audio-modes {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  padding: 0 24px 28px;
}

/* ---------- BUTTONS ---------- */
.anr-btn,
.anr-fs-btn {
  font-family: var(--font-sans);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 9px 16px;
  border: 1px solid var(--hairline);
  background: var(--bg);
  color: var(--fg);
  cursor: pointer;
  border-radius: 0;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.anr-btn:hover,
.anr-fs-btn:hover {
  background: var(--fg);
  color: var(--bg);
}
.anr-btn:disabled,
.anr-fs-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  background: var(--bg);
  color: var(--fg);
}
.anr-btn.is-active,
.anr-btn.is-recording {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}
.anr-rec-dot { color: currentColor; font-size: 0.9em; vertical-align: middle; }
.anr-btn.is-recording .anr-rec-dot { animation: anr-blink 1s steps(2, end) infinite; }
@keyframes anr-blink { 50% { opacity: 0; } }

.anr-btn-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.anr-frame-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 8px 0; }
.anr-frame-grid > .anr-btn { width: 100%; }

.anr-timecode {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 6px 12px;
  border: 1px solid var(--hairline);
  background: var(--bg);
  cursor: pointer;
}
.anr-timecode-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1;
  margin-bottom: 2px;
}
.anr-timecode-value {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.anr-timecode-input {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  text-align: center;
  width: 100%;
  border: none;
  background: transparent;
  color: inherit;
  outline: none;
  padding: 0;
}
.anr-frame-wrap { margin: 8px 0; }
.anr-frame-wrap .anr-frame-grid { margin: 0; }
.anr-timecode-hint {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.12em;
  color: var(--muted);
  margin-bottom: 6px;
  line-height: 1;
  text-align: center;
  display: block;
}
.anr-timecode:hover { border-color: var(--fg); }
:root[data-theme="dark"] .anr-timecode { background: var(--surface); }

/* ---------- RESULTS / CARDS ---------- */
.anr-results { margin: 0; scroll-margin-top: var(--nav-offset); }

.anr-card {
  margin: 0 0 56px;
  padding: 0;
  background: transparent;
  border: none;
}
.anr-card h3 {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg);
  font-weight: 500;
  margin: 0 0 14px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}
/* Collapsible analysis cards. Every card title (a direct-child <h3>) toggles its
   own body open/closed; cards render open, so the expanded view is unchanged save
   for the +/- disclosure glyph used everywhere else on the site (details summary).
   JS adds .is-collapsed on click. Open = minus, collapsed = plus. */
.anr-card > h3 {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  user-select: none;
}
.anr-card > h3::after {
  content: "\2212";                  /* minus = open */
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1;
  color: var(--muted);
  flex: none;
  transition: color 0.15s ease;
}
.anr-card > h3:hover { color: var(--accent); }
.anr-card > h3:hover::after { color: var(--accent); }
.anr-card.is-collapsed > h3 { margin-bottom: 0; }
.anr-card.is-collapsed > h3::after { content: "+"; }   /* plus = closed */
.anr-card.is-collapsed > :not(h3) { display: none; }
.anr-card-empty { color: var(--muted); font-style: italic; }

/* ---------- PREVIEW ---------- */
.anr-preview {
  background: var(--surface);
  padding: 16px;
  border: 1px solid var(--rule);
  text-align: center;
}
.anr-preview img {
  max-width: 100%;
  max-height: 480px;
  display: inline-block;
}
.anr-preview-meta {
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: left;
}

/* ---------- READOUT TABLE ---------- */
.anr-readout {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-feature-settings: "tnum";
}
.anr-readout th,
.anr-readout td {
  text-align: left;
  padding: 9px 12px 9px 0;
  vertical-align: top;
  border-bottom: 1px solid var(--rule);
  word-break: break-all;
  overflow-wrap: anywhere;
}
.anr-readout th {
  font-weight: 400;
  color: var(--muted);
  width: 38%;
  text-transform: none;
}
.anr-readout td { color: var(--fg); font-weight: 500; }
.anr-readout tr:last-child th,
.anr-readout tr:last-child td { border-bottom: none; }
.anr-readout tr:hover th,
.anr-readout tr:hover td { background: var(--surface); }

.anr-readout-section {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 28px 0 6px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline);
}
.anr-readout-section:first-of-type { border-top: none; margin-top: 0; padding-top: 0; }

/* ---------- HISTOGRAM / WAVEFORM ---------- */
.anr-histogram,
.anr-waveform {
  width: 100%;
  display: block;
  background: var(--media-bg);
  border: 1px solid var(--hairline);
}
/* No fixed aspect ratio: width:100% with height auto lets the canvas scale to
   its own 1024x200 pixels at any window size. */
.anr-histogram { height: auto; }
.anr-hist-block { margin: 0 0 56px; }   /* same body rhythm as .anr-card */
.anr-waveform { height: 96px; }

.anr-playhead {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 1px;
  background: var(--on-dark);
  pointer-events: none;
  z-index: 3;
  will-change: left;
}

/* ---------- PALETTE ---------- */
.anr-palette {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--hairline);
  border-left: 1px solid var(--hairline);
}
.anr-swatch {
  aspect-ratio: 1 / 1;
  position: relative;
  font-family: var(--font-mono);
  font-size: clamp(8px, 1.1vw, 11px);
  color: var(--fg);
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  overflow: hidden;
}
.anr-swatch {
  transition: transform 0.15s ease;
}
.anr-swatch:hover {
  transform: translateY(-3px);
  z-index: 2;
  box-shadow: 0 0 0 1px var(--hairline);
}
.anr-swatch span {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 4px 4px;
  background: var(--bg);
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  border-top: 1px solid var(--hairline);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: clip;
}
/* On phones, two rows of four (4x2) are friendlier than eight tiny squares.
   600px so it catches every phone in portrait - the old 420px missed the wider
   modern handsets (Pro Max ~430, large Androids 412-480), leaving them at 8. */
@media (max-width: 600px) {
  .anr-palette { grid-template-columns: repeat(4, 1fr); }
}

/* ---------- MAP ---------- */
.anr-map {
  width: 100%;
  height: 360px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  position: relative;
  z-index: 1;
}

/* ---------- SPECTROGRAM ---------- */
.anr-spec-card { position: relative; }

.anr-spec-wrap {
  display: flex;
  background: var(--media-bg);
  border: 1px solid var(--hairline);
  position: relative;
  min-height: 0;
}

.anr-spec-yaxis-wrap { flex: 0 0 48px; display: flex; flex-direction: column; }
.anr-spec-yaxis {
  flex: 1 1 auto;
  position: relative;
  background: var(--media-bg);
  border-right: 1px solid var(--hairline-on-dark);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  color: var(--muted-on-dark);
  overflow: hidden;
}
.anr-spec-yaxis span { position: absolute; right: 6px; transform: translateY(-50%); letter-spacing: 0.04em; }
.anr-spec-corner {
  height: 20px;
  background: var(--media-bg);
  border-right: 1px solid var(--hairline-on-dark);
  border-top: 1px solid var(--hairline-on-dark);
}

.anr-spec-scroll {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  display: flex;
  flex-direction: column;
  background: var(--media-bg);
  -webkit-overflow-scrolling: touch;
  scrollbar-color: var(--border-on-dark-ctl) var(--media-bg);
  scrollbar-width: thin;
}
/* The native scrollbar is hidden - a custom one (.anr-spec-sb) is rendered under
   the spectrogram instead. Scrolling itself (wheel / trackpad / playhead-follow)
   still works through this overflow container. */
.anr-spec-scroll { scrollbar-width: none; }
.anr-spec-scroll::-webkit-scrollbar { height: 0; width: 0; display: none; }

/* Custom horizontal scrollbar, shown under the canvas only when zoomed in. The
   leading spacer matches the y-axis column so the track sits under the canvas. */
.anr-spec-sb { display: flex; margin-top: 6px; }
.anr-spec-sb.is-hidden { display: none; }
.anr-spec-sb-spacer { flex: 0 0 48px; }
.anr-spec-sb-track {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 12px;
  background: var(--media-bg);
  border: 1px solid var(--hairline);
  cursor: pointer;
  touch-action: none;
}
.anr-spec-sb-thumb {
  position: absolute;
  top: 1px;
  left: 0;
  height: calc(100% - 2px);
  width: 40px;
  background: var(--border-on-dark-ctl);
  cursor: grab;
  will-change: transform;
}
.anr-spec-sb-thumb:hover { background: var(--hairline-strong); }
.anr-spec-sb-track.is-dragging .anr-spec-sb-thumb,
.anr-spec-sb-thumb:active { background: var(--accent); cursor: grabbing; }

.anr-spec-canvas-wrap { position: relative; flex: 0 0 auto; }
.anr-spec-canvas { display: block; image-rendering: pixelated; }
.anr-spec-xaxis {
  height: 20px; flex: 0 0 auto;
  background: var(--media-bg);
  border-top: 1px solid var(--hairline-on-dark);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  color: var(--muted-on-dark);
  position: relative;
  pointer-events: none;
}
.anr-spec-xaxis span { position: absolute; top: 4px; transform: translateX(-50%); letter-spacing: 0.04em; }

/* fullscreen */
.anr-spec-card:fullscreen,
.anr-spec-card:-webkit-full-screen {
  background: var(--media-bg);
  padding: 20px;
  margin: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.anr-spec-card:fullscreen h3,
.anr-spec-card:-webkit-full-screen h3 {
  color: var(--on-dark);
  border-bottom-color: var(--hairline-on-dark);
  flex: 0 0 auto;
}
.anr-spec-card:fullscreen .anr-controls,
.anr-spec-card:-webkit-full-screen .anr-controls {
  flex: 0 0 auto;
  background: var(--surface-on-dark);
  border-color: var(--hairline-on-dark);
}
.anr-spec-card:fullscreen .anr-controls label,
.anr-spec-card:-webkit-full-screen .anr-controls label { color: var(--muted-on-dark); }
.anr-spec-card:fullscreen .anr-controls select,
.anr-spec-card:-webkit-full-screen .anr-controls select {
  background: var(--surface-on-dark);
  color: var(--on-dark);
  border-color: var(--border-on-dark-ctl);
}
/* Center the spectrogram vertically in the available area when it's shorter than
   the screen. The canvas-wrap fills the remaining height and the canvas fills it
   via height:100%, so the spectrogram fills the screen with no gap. Scoped to the
   file panel's canvas-wrap so the live card (canvas directly in the scroll) keeps
   its own JS sizing. */
.anr-spec-card:fullscreen .anr-spec-canvas-wrap,
.anr-spec-card:-webkit-full-screen .anr-spec-canvas-wrap { flex: 1 1 0; min-height: 0; }
.anr-spec-card:fullscreen .anr-spec-canvas-wrap > .anr-spec-canvas,
.anr-spec-card:-webkit-full-screen .anr-spec-canvas-wrap > .anr-spec-canvas { height: 100%; }
/* Height is meaningless in fullscreen (the canvas auto-fills), so hide it. */
.anr-spec-card:fullscreen .anr-ctl-height,
.anr-spec-card:-webkit-full-screen .anr-ctl-height { display: none; }

/* Floating exit-fullscreen button (top-right), only shown while fullscreen. */
.anr-spec-fs-close { display: none; }
.anr-spec-card:fullscreen .anr-spec-fs-close,
.anr-spec-card:-webkit-full-screen .anr-spec-fs-close {
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 10;
  width: 34px;
  height: 34px;
  font-size: 16px;
  line-height: 1;
  background: var(--surface-on-dark);
  color: var(--on-dark);
  border: 1px solid var(--border-on-dark-ctl);
  cursor: pointer;
}
.anr-spec-card:fullscreen .anr-spec-fs-close:hover,
.anr-spec-card:-webkit-full-screen .anr-spec-fs-close:hover { background: var(--on-dark); color: var(--media-bg); }
.anr-spec-card:fullscreen .anr-spec-wrap,
.anr-spec-card:-webkit-full-screen .anr-spec-wrap {
  flex: 1 1 auto;
  min-height: 0;
  border-color: var(--hairline-on-dark);
}
.anr-spec-card:fullscreen .anr-spec-hint,
.anr-spec-card:-webkit-full-screen .anr-spec-hint { color: var(--muted-on-dark); }
.anr-spec-card:fullscreen .anr-fs-btn,
.anr-spec-card:-webkit-full-screen .anr-fs-btn {
  background: var(--surface-on-dark); color: var(--on-dark); border-color: var(--border-on-dark-ctl);
}
.anr-spec-card:fullscreen .anr-fs-btn:hover,
.anr-spec-card:-webkit-full-screen .anr-fs-btn:hover { background: var(--on-dark); color: var(--media-bg); }
.anr-spec-card:fullscreen .anr-toggle,
.anr-spec-card:-webkit-full-screen .anr-toggle { border-color: var(--border-on-dark-ctl); }
.anr-spec-card:fullscreen .anr-toggle button,
.anr-spec-card:-webkit-full-screen .anr-toggle button { color: var(--muted-on-dark); }
.anr-spec-card:fullscreen .anr-toggle button.is-active,
.anr-spec-card:-webkit-full-screen .anr-toggle button.is-active { background: var(--on-dark); color: var(--media-bg); }
/* Dark-theme the rest of the controls so the newer additions (Sensitivity slider,
   Save / Record / Live buttons) and the stats readout match the fullscreen palette. */
.anr-spec-card:fullscreen .anr-btn,
.anr-spec-card:-webkit-full-screen .anr-btn {
  background: var(--surface-on-dark); color: var(--on-dark); border-color: var(--border-on-dark-ctl);
}
.anr-spec-card:fullscreen .anr-btn:hover,
.anr-spec-card:-webkit-full-screen .anr-btn:hover { background: var(--on-dark); color: var(--media-bg); }
.anr-spec-card:fullscreen .anr-btn.is-active,
.anr-spec-card:fullscreen .anr-btn.is-recording,
.anr-spec-card:-webkit-full-screen .anr-btn.is-active,
.anr-spec-card:-webkit-full-screen .anr-btn.is-recording {
  background: var(--accent); color: var(--accent-fg); border-color: var(--accent);
}
.anr-spec-card:fullscreen input[type="range"]::-webkit-slider-runnable-track,
.anr-spec-card:-webkit-full-screen input[type="range"]::-webkit-slider-runnable-track { background: var(--border-on-dark-ctl); }
.anr-spec-card:fullscreen input[type="range"]::-moz-range-track,
.anr-spec-card:-webkit-full-screen input[type="range"]::-moz-range-track { background: var(--border-on-dark-ctl); }
.anr-spec-card:fullscreen .anr-range-readout,
.anr-spec-card:-webkit-full-screen .anr-range-readout { color: var(--on-dark); }
/* Keep the stats + status rows to a single, fixed-height line in fullscreen.
   Otherwise their text re-wraps as values change per setting, and since the
   canvas height is the flex remainder, a taller row would shrink the canvas
   (settings appeared to randomly grow/shrink the spectrogram). */
.anr-spec-card:fullscreen .anr-spec-stats,
.anr-spec-card:-webkit-full-screen .anr-spec-stats {
  color: var(--muted-on-dark);
  grid-auto-flow: column;
  grid-auto-columns: max-content;
  grid-template-columns: none;
  overflow: hidden;
}
.anr-spec-card:fullscreen .anr-spec-hint,
.anr-spec-card:-webkit-full-screen .anr-spec-hint {
  white-space: nowrap; overflow: hidden;
}
.anr-spec-card:fullscreen .anr-spec-stat-val,
.anr-spec-card:-webkit-full-screen .anr-spec-stat-val { color: var(--on-dark); }

/* ---------- CONTROLS ROW ---------- */
.anr-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 22px;
  align-items: center;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-bottom: none;
  font-family: var(--font-sans);
  font-size: var(--t-small);
}
.anr-control { display: flex; align-items: center; gap: 8px; }
.anr-control label {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
/* A label that resets its control when clicked. */
.anr-control label.anr-resettable { cursor: pointer; }
.anr-control label.anr-resettable:hover { color: var(--accent); }

/* Actions row pulled out from the settings and placed under the scrubber: give
   it a full border (the settings .anr-controls has no bottom border because it
   butts against the canvas) and a little breathing room above. */
.anr-spec-actions {
  border-bottom: 1px solid var(--hairline);
  margin-top: 10px;
}

/* Segmented control groups (View / Resolution / Actions) - a captioned cluster
   with a hairline divider on its left edge. align-self:stretch makes the divider
   span the full row height even though the row centres its items. */
.anr-control-group {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  align-self: stretch;
  padding: 0 18px;
  border-left: 1px solid var(--hairline);
}
.anr-control-group:first-child { padding-left: 0; border-left: none; }
.anr-control-group-label {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.7;
}
.anr-control-group-items {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}

/* "Advanced" disclosure inside the spectrogram settings row: collapses the
   analysis params (Mode / FFT / Window) behind the site's standard <details>
   +/- toggle. Spans the full row width so it opens onto its own line under the
   View controls, with a hairline divider separating it from them. */
.anr-spec-advanced {
  flex: 1 1 100%;
  border: none;
  border-top: 1px solid var(--hairline);
  margin: 2px 0 0;
  padding: 11px 0 2px;
}
.anr-spec-advanced > summary {
  color: var(--muted);
  letter-spacing: 0.14em;
  opacity: 0.7;
}
.anr-spec-advanced[open] > summary { opacity: 1; }
.anr-spec-advanced > .anr-control-group-items { margin-top: 12px; }
.anr-control select,
.anr-control input[type="number"],
.anr-control input[type="text"] {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  padding: 5px 8px;
  border: 1px solid var(--hairline);
  background: var(--bg);
  color: var(--fg);
  border-radius: 0;
}
/* Custom range to match the site: a hairline track with a thin, square accent
   thumb (no rounded corners) instead of the rounded native control. */
.anr-control input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 120px;
  height: 16px;
  background: transparent;
  cursor: pointer;
}
.anr-control input[type="range"]::-webkit-slider-runnable-track {
  height: 3px; background: var(--hairline); border-radius: 0;
}
.anr-control input[type="range"]::-moz-range-track {
  height: 3px; background: var(--hairline); border-radius: 0;
}
.anr-control input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 4px; height: 14px;
  margin-top: -5.5px;          /* centre the thumb on the 3px track */
  background: var(--accent); border: 0; border-radius: 0;
}
.anr-control input[type="range"]::-moz-range-thumb {
  width: 4px; height: 14px;
  background: var(--accent); border: 0; border-radius: 0;
}
.anr-control input[type="range"]:focus { outline: none; }
.anr-control input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 2px var(--bg), 0 0 0 3px var(--accent); }
.anr-control input[type="range"]:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 2px var(--bg), 0 0 0 3px var(--accent); }
.anr-control input[type="range"]:hover::-webkit-slider-thumb { background: var(--fg); }
.anr-control input[type="range"]:hover::-moz-range-thumb { background: var(--fg); }
.anr-range-readout {
  display: inline-block; min-width: 38px; text-align: right;
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: var(--t-small);
}

/* At-a-glance spectrogram stats strip (under the canvas) */
/* Stats block under the spectrogram: a captioned header with a [?] toggle, then
   a tidy grid of labelled value cells. */
.anr-spec-statsblock { margin: 10px 0 0; }
.anr-spec-stats-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-top: 1px solid var(--hairline);
  padding-top: 10px;
}
.anr-spec-stats-title {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  opacity: 0.7;
}
/* The [?] in this header is a flex item, so neutralise .anr-info-btn's float. */
.anr-spec-stats-head .anr-info-btn { float: none; }
.anr-spec-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 14px 20px;
  margin: 14px 0 0;
}
.anr-spec-stat { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.anr-spec-stat-label {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.anr-spec-stat-val {
  font-family: var(--font-mono);
  font-size: var(--t-body);
  color: var(--fg);
  line-height: 1.3;
}
.anr-spec-stat-sub { color: var(--muted); font-size: var(--t-small); white-space: nowrap; }

.anr-toggle { display: inline-flex; border: 1px solid var(--hairline); }
.anr-toggle button {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  padding: 5px 10px;
  background: transparent;
  border: none;
  color: var(--fg);
  cursor: pointer;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.anr-toggle button:hover:not(.is-active) { color: var(--accent); }
.anr-toggle button.is-active { background: var(--fg); color: var(--bg); }

.anr-spec-hint {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* ---------- INFO BUTTON / PANEL ---------- */
.anr-info-btn {
  float: right;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 0;
  line-height: inherit;
}
.anr-info-btn:hover { color: var(--accent); }
/* Label + [?] grouped on the left of a flex `summary` (which is space-between, so
   only the open/close marker sits at the right edge). */
.anr-summary-label { display: inline-flex; align-items: center; gap: 8px; }
.anr-summary-label .anr-info-btn { float: none; }

/* ---------- TIP POPUP (inline row help) ---------- */
.anr-readout th { position: relative; }
.anr-tip-btn {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 0;
  line-height: inherit;
  opacity: 0.4;
}
.anr-tip-btn:hover { color: var(--accent); opacity: 1; }
.anr-tip {
  display: none;
  position: absolute;
  bottom: calc(100% + 4px);
  left: 0;
  z-index: 100;
  min-width: 260px;
  max-width: 380px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  line-height: 1.65;
  letter-spacing: 0.02em;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-popover);
  white-space: normal;
  word-break: normal;
}
.anr-tip.is-active { display: block; }
.anr-info-panel {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  line-height: 1.7;
  letter-spacing: 0.02em;
  padding: 12px 0 16px;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 14px;
}
.anr-info-panel strong {
  color: var(--fg);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* ---------- CUSTOM PLAYER ---------- */
.anr-player {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  margin-bottom: 14px;
}
.anr-player-play {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hairline);
  background: var(--bg);
  color: var(--fg);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
  font-family: var(--font-sans);
  line-height: 1;
  transition: background 0.12s ease, color 0.12s ease;
}
.anr-player-play:hover {
  background: var(--fg);
  color: var(--bg);
}
.anr-player-track {
  flex: 1 1 auto;
  height: 32px;
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: center;
}
.anr-player-track::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  height: 3px;
  background: var(--rule);
}
.anr-player-fill {
  height: 3px;
  background: var(--accent);
  width: 0%;
  pointer-events: none;
  position: relative;
  z-index: 1;
}
.anr-player-time {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.06em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  min-width: 80px;
  text-align: right;
}

/* ---------- TRANSPORT ---------- */
.anr-transport { display: flex; gap: 8px; align-items: center; margin: 12px 0; }
.anr-transport audio { flex: 1; min-width: 0; }
audio { width: 100%; }

/* ---------- PROGRESS ---------- */
.anr-progress {
  margin: 18px 0 20px;
}
.anr-progress-bar {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 900;
  white-space: pre;
  line-height: 1.4;
  overflow: hidden;
  color: var(--fg);
}
.anr-progress-bar .anr-bar-fill {
  color: var(--accent);
}
.anr-progress-label {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1.3;
  min-height: 1.3em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 4px;
}

/* ---------- DROP LOADER (bottom-of-window popup) ---------- */
.anr-drop-loader {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%) translateY(14px);
  z-index: 1200;
  width: min(360px, calc(100vw - 32px));
  background: var(--bg);
  border: 1px solid var(--rule);
  box-shadow: var(--shadow-popover);
  padding: 12px 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.anr-drop-loader.is-open { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
/* Label + Cancel share one line: label fills the left, button hugs the right. */
.anr-drop-loader-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 8px;
}
.anr-drop-loader-label {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  min-width: 0;
}
.anr-drop-loader-cancel {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color 0.15s ease;
}
.anr-drop-loader-cancel:hover { color: var(--fg); }
/* The drop loader's bar: a continuously scrolling strip of accent slashes
   inside brackets ([////////]). The motion is a pure CSS `transform`, NOT a
   requestAnimationFrame loop - rAF runs on the main thread, so it froze
   whenever the file's heavy synchronous work (FFTs, BPM, pixel stats) blocked
   it. A transform animation runs on the compositor and keeps moving regardless. */
.anr-css-bar {
  display: flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 900;
  line-height: 1.2;
  color: var(--fg);
}
.anr-css-bar-track {
  position: relative;
  flex: 1 1 auto;
  height: 1.2em;
  overflow: hidden;
  margin: 0 1px;
}
.anr-css-bar-win {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 25%;                 /* the bouncing window, matching asciiBar's round(W*0.25) */
  white-space: pre;
  overflow: hidden;           /* clip the slash pile to a solid 25%-wide block */
  color: var(--accent);
  will-change: transform;
  /* steps() makes it jump in discrete chunks - choppy, like the original ASCII
     bar's character-by-character stepping - rather than a smooth glide. */
  animation: anr-css-bar-bounce 1.9s steps(16) infinite alternate;
}
/* Paused while the popup is hidden so it costs nothing between loads. */
.anr-drop-loader:not(.is-open) .anr-css-bar-win { animation-play-state: paused; }
/* The window is 25% of the track wide, so 300% of its own width = 75% of the
   track: left edge → right edge. `alternate` + linear timing reproduces the
   original asciiBar's triangle bounce (it swept ~1.9 s each way). */
@keyframes anr-css-bar-bounce {
  from { transform: translateX(0); }
  to   { transform: translateX(300%); }
}
@media (prefers-reduced-motion: reduce) {
  .anr-css-bar-win { animation: none; }
}
/* Inline per-card loader (e.g. building a folder treemap) */
.anr-inline-loader {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
}
.anr-inline-loader-label {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
/* Keep the ASCII bar at its full character width - flex shrink would otherwise
   clip its trailing "]" since .anr-progress-bar is overflow:hidden. */
.anr-inline-loader .anr-progress-bar { flex: 0 0 auto; }
/* Embedded cover art (audio) */
.anr-coverart {
  display: block;
  max-width: 240px;
  max-height: 240px;
  border: 1px solid var(--hairline);
  margin-bottom: 14px;
}

/* MIDI instrument / track lists */
.anr-midi-list { margin: 0; padding-left: 20px; font-size: var(--t-small); line-height: 1.7; color: var(--fg); }
.anr-midi-list li { word-break: break-word; }

/* GPX/KML/GeoJSON map */
.anr-geo-map { width: 100%; height: 380px; border: 1px solid var(--hairline); background: var(--surface); }
.anr-geo-map .anr-hint { padding: 16px; }

/* LRC timed-lyrics list */
.anr-lrc-list { max-height: 460px; overflow: auto; font-size: var(--t-small); line-height: 1.5; }
.anr-lrc-line { display: flex; gap: 12px; padding: 1px 0; }
.anr-lrc-time {
  flex: 0 0 auto; min-width: 56px; text-align: right;
  font-family: var(--font-mono); color: var(--muted);
}
.anr-lrc-text { flex: 1 1 auto; word-break: break-word; }

/* Embedded lyrics block */
.anr-lyrics {
  margin: 0;
  max-height: 360px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: var(--font-sans);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--fg);
}

/* ---------- OCR ---------- */
.anr-ocr-text {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  background: var(--surface);
  color: var(--fg);
  padding: 16px;
  border: 1px solid var(--hairline);
  max-height: 360px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  margin: 28px 0 0;
  line-height: 1.5;
}
.anr-ocr-text:empty::before { content: "(no text detected)"; color: var(--muted); font-style: italic; }

/* ---------- BANNERS ---------- */
.anr-error {
  background: var(--accent);
  color: var(--accent-fg);
  padding: 14px 18px;
  margin: 16px 0;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  letter-spacing: 0.02em;
}
.anr-cloud-warning { line-height: 1.55; }
.anr-cloud-warning ul { line-height: 1.55; }
.anr-info {
  background: var(--surface);
  border: 1px solid var(--rule);
  color: var(--fg);
  padding: 14px 18px;
  margin: 16px 0;
  font-family: var(--font-mono);
  font-size: var(--t-small);
}

/* ---------- DEFINITION LIST (About) ---------- */
.anr-defs {
  margin: 28px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 0 32px;
}
.anr-defs dt {
  border-top: 1px solid var(--hairline);
  padding: 18px 0 8px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--muted);
}
.anr-defs dd {
  border-top: 1px solid var(--hairline);
  padding: 18px 0 8px;
  margin: 0;
  font-size: var(--t-body);
}
@media (max-width: 700px) {
  .anr-defs { grid-template-columns: 1fr; gap: 0; }
  .anr-defs dt { padding-bottom: 0; }
  .anr-defs dd { border-top: none; padding-top: 4px; padding-bottom: 18px; }
}

/* ---------- DETAILS (raw dump) ---------- */
details {
  border-top: 1px solid var(--hairline);
  padding: 16px 0 4px;
  margin: 24px 0 0;
}
details summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg);
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
details summary::-webkit-details-marker { display: none; }
details summary:hover { color: var(--accent); }
details summary::after {
  content: "+";
  font-family: var(--font-mono);
  font-size: 16px;
  color: var(--muted);
  transition: color 0.15s ease;
}
details summary:hover::after { color: var(--accent); }
details[open] summary::after { content: "\2212"; }

/* ---------- ABOUT / FOOTER ---------- */
.site-footer--about {
  background: var(--fg);
  color: var(--bg);
  border-top: none;
  padding: clamp(40px, 6vw, 64px) var(--pad-x);
  max-width: none;
  scroll-margin-top: var(--nav-offset);
}
.site-footer--about a { color: var(--bg); }
.site-footer--about a:hover { color: var(--accent); }
.footer-about-heading {
  margin-bottom: 28px;
}
.footer-about-heading .footer-mark {
  font-size: var(--t-h2);
  font-weight: 500;
  letter-spacing: -0.01em;
}
.footer-about-heading .footer-meta {
  color: rgba(255,255,255,0.5);
  margin-top: 4px;
}
.about-defs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0 var(--gap);
  margin: 0 0 32px;
  padding: 0;
}
.about-defs > div {
  border-top: 1px solid rgba(255,255,255,0.15);
  padding: 12px 0;
}
.about-defs dt {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: rgba(255,255,255,0.4);
  margin: 0 0 2px;
}
.about-defs dd {
  margin: 0;
  font-size: var(--t-small);
  color: rgba(255,255,255,0.8);
}
.about-details {
  border-top: none;
  padding: 0;
  margin: 0 0 24px;
}
/* Outlined button - same border language as the offline tiers + Install/Clear. */
.about-details summary {
  display: inline-flex;
  width: max-content;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  color: rgba(255,255,255,0.8);
  background: transparent;
  border: 1px solid rgba(255,255,255,0.15);
  padding: 6px 14px;
  letter-spacing: 0.08em;
}
.about-details summary:hover { color: var(--accent); border-color: rgba(255,255,255,0.5); }
/* Match the label size so the marker doesn't make the button taller than the
   sibling Install/Clear buttons. */
.about-details summary::after { color: rgba(255,255,255,0.4); font-size: var(--t-tiny); line-height: 1; }
.about-details[open] summary { margin-bottom: 16px; }
.about-details .about-defs { margin: 0; }
/* Dependencies now lives in the Install/Clear button row. Drop its margin, and
   when opened let it take a full-width line of its own so the definition grid
   isn't squeezed into the narrow flex item. */
.offline-bottom-row .about-details { margin: 0; display: flex; flex-direction: column; }
.offline-bottom-row .about-details summary { justify-content: center; box-sizing: border-box; width: 100%; }
/* Closed: also stretch to the row height so it matches the other two buttons. */
.offline-bottom-row .about-details:not([open]) summary { flex: 1 1 auto; }
/* Open: span the full row; the remaining two buttons split it in half (below). */
.offline-bottom-row .about-details[open] { grid-column: 1 / -1; }
.offline-bottom-row:has(.about-details[open]) { grid-template-columns: repeat(2, 1fr); }

.offline-section {
  border-top: 1px solid rgba(255,255,255,0.15);
  padding-top: 24px;
  margin-bottom: 24px;
}
.offline-heading {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
  margin: 0 0 12px;
}
.offline-heading-row { display: flex; align-items: baseline; gap: 8px; margin-bottom: 12px; }
.offline-heading-row .offline-heading { margin-bottom: 0; }
/* [?] dropdown listing each download tier - only shown on mobile, where the
   per-tier descriptions are hidden. Same plain "[?]" style as the rest of the
   site (.anr-info-btn), tinted for the dark footer. */
.offline-help { display: none; }
.offline-help-btn {
  display: inline-block;   /* not list-item -> no disclosure +/- marker */
  list-style: none; cursor: pointer; user-select: none;
  font-family: var(--font-mono); font-size: var(--t-tiny); letter-spacing: 0.08em;
  color: rgba(255,255,255,0.5); padding: 0;
}
.offline-help-btn::-webkit-details-marker { display: none; }
.offline-help-btn::marker { content: ''; }
/* The generic `details summary::after` adds a +/- disclosure glyph; the offline
   [?] is a plain help toggle, so suppress it in both states. */
.offline-help-btn::after,
.offline-help[open] .offline-help-btn::after { content: none; }
.offline-help-btn:hover,
.offline-help[open] .offline-help-btn { color: var(--accent); }
/* The panel is a normal-flow block (a real dropdown that pushes the download
   buttons down), revealed when the [?] details is open. */
.offline-help-panel { display: none; margin: 0 0 14px; }
.offline-section:has(.offline-help[open]) .offline-help-panel { display: block; }
.offline-help-panel > div {
  padding: 8px 0; border-top: 1px solid rgba(255,255,255,0.12);
  font-family: var(--font-sans); font-size: var(--t-small); line-height: 1.45;
  color: rgba(255,255,255,0.8);
}
.offline-help-panel > div:first-child { border-top: none; }
.offline-help-panel strong {
  color: var(--on-dark); font-family: var(--font-mono); font-size: var(--t-tiny);
  text-transform: uppercase; letter-spacing: 0.08em;
}
.offline-help-panel span { color: rgba(255,255,255,0.45); font-size: 11px; margin-left: 6px; }
.offline-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
/* Let the tier tracks resolve to a strict 1fr (same as .offline-bottom-row),
   so the download buttons and the Install/Clear/Dependencies row are identical
   widths - content can't push a track wider than its third. */
.offline-options > * { min-width: 0; }
/* Failure note under the download buttons (created by app.js on a failed tier). */
.offline-status {
  margin: 14px 0 0;
  padding-left: 10px;
  border-left: 2px solid var(--accent);
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  line-height: 1.6;
  letter-spacing: 0.03em;
  color: var(--accent);
}
.offline-status[hidden] { display: none; }

/* Same 3-column grid as the download tiers above, so Install / Clear /
   Dependencies line up at the same width as the download buttons. This base
   MUST precede the @media block below - equal specificity means source order
   decides, so a later base would otherwise clobber the mobile gap override. */
.offline-bottom-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 10px;
}
.offline-bottom-row > * { min-width: 0; }   /* let labels wrap instead of widening the track */

/* Keep the three tiers on one row even on mobile; drop the long descriptions
   there so the compact name + size cards fit across a narrow screen. */
@media (max-width: 700px) {
  .offline-options { gap: 6px; }
  .offline-btn { padding: 10px 8px; }
  .offline-tier { font-size: var(--t-tiny); }
  .offline-desc { display: none; }
  /* Descriptions are hidden here, so reveal the [?] that lists them instead. */
  .offline-help { display: block; }
  .offline-size { font-size: 10px; }
  /* Match the tiers' tighter mobile gap and let labels wrap inside their cell. */
  .offline-bottom-row { gap: 6px; }
  .offline-bottom-row .offline-install,
  .offline-bottom-row .offline-clear,
  .offline-bottom-row .about-details summary {
    padding: 6px 4px;
    text-align: center;
    overflow-wrap: break-word;
  }
  /* "Dependencies" can't wrap (one word); drop the +/- marker so it fits. */
  .offline-bottom-row .about-details summary::after { display: none; }
  .offline-bottom-row .about-details summary { gap: 0; }
  /* Install's instruction message expands full width like an opened Dependencies
     (mobile only); Clear + Dependencies then split the row beneath it. */
  .offline-bottom-row .offline-install.is-expanded { grid-column: 1 / -1; }
  .offline-bottom-row:has(.offline-install.is-expanded) { grid-template-columns: repeat(2, 1fr); }
}
.offline-btn {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid rgba(255,255,255,0.15);
  background: transparent;
  color: rgba(255,255,255,0.8);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  transition: border-color 0.2s ease, background 0.2s ease;
}
/* "Recommended" crown badge, top-right of the Everything tier. Faint + decorative
   (pointer-events:none so it never intercepts the button click). */
.offline-rec {
  position: absolute;
  top: 8px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  pointer-events: none;
  color: rgba(255,255,255,0.5);
}
.offline-rec-crown { width: 14px; height: auto; display: block; }
.offline-rec-text {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
}
@media (max-width: 700px) {
  /* Keep just the crown when the buttons get narrow. */
  .offline-rec { top: 6px; right: 6px; }
  .offline-rec-text { display: none; }
}
.offline-btn:hover { border-color: rgba(255,255,255,0.5); background: rgba(255,255,255,0.05); }
.offline-btn.is-done { border-color: var(--accent); }
.offline-btn.is-done.is-fading { border-color: rgba(255,255,255,0.15); transition: border-color 1s ease; }
.offline-btn.is-active { border-color: rgba(255,255,255,0.6); }
.offline-tier {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.offline-desc {
  font-size: 12px;
  color: rgba(255,255,255,0.4);
  line-height: 1.3;
}
.offline-size {
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255,255,255,0.35);
  margin-top: 2px;
}
.offline-bar {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 900;
  white-space: pre;
  overflow: hidden;
  color: rgba(255,255,255,0.3);
  margin-top: 6px;
  line-height: 1;
}
.offline-bar .offline-bar-fill {
  color: rgba(255,255,255,0.8);
}
.offline-btn.is-done .offline-bar .offline-bar-fill { color: var(--accent); }
.offline-btn.is-done.is-fading .offline-bar .offline-bar-fill { color: rgba(255,255,255,0.8); transition: color 1s ease; }
/* "✓ Cached" badge pinned to the bottom of a tier button once its files are in
   the offline cache. Persisted across reloads via localStorage; the accent tint
   stays even after the border fades, so the cached tier reads at a glance. */
.offline-cached[hidden] { display: none; }
.offline-cached {
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 5px;
}
@media (max-width: 700px) { .offline-cached { font-size: 9px; } }

/* Install + Clear share the same outlined button shape as everything else.
   Clear keeps muted text so the destructive action stays de-emphasised. */
.offline-install,
.offline-clear {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.15);
  cursor: pointer;
  padding: 6px 14px;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.offline-install { color: rgba(255,255,255,0.8); }
.offline-install:hover { border-color: rgba(255,255,255,0.5); color: var(--accent); }
.offline-clear { color: rgba(255,255,255,0.4); }
.offline-clear:hover { border-color: rgba(255,255,255,0.5); color: rgba(255,255,255,0.8); }

:root[data-theme="dark"] .offline-section { border-top-color: #333; }
:root[data-theme="dark"] .offline-btn { border-color: #333; }
:root[data-theme="dark"] .offline-btn:hover { border-color: #555; background: rgba(255,255,255,0.03); }
:root[data-theme="dark"] .offline-install,
:root[data-theme="dark"] .offline-clear,
:root[data-theme="dark"] .about-details summary { border-color: #333; }
:root[data-theme="dark"] .offline-install:hover,
:root[data-theme="dark"] .offline-clear:hover,
:root[data-theme="dark"] .about-details summary:hover { border-color: #555; }

.footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.15);
  padding-top: 24px;
}
.footer-bottom .footer-meta { color: rgba(255,255,255,0.4); }
.footer-bottom .footer-meta a { color: rgba(255,255,255,0.5); }
/* Cross-page nav button in the footer bottom row (About ↔ Main page). Outlined
   to match the offline buttons; text colour comes from .site-footer--about a. */
.footer-nav-btn {
  align-self: center;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid rgba(255,255,255,0.15);
  padding: 6px 14px;
  text-decoration: none;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.footer-nav-btn:hover { border-color: rgba(255,255,255,0.5); }
:root[data-theme="dark"] .footer-nav-btn { border-color: #333; }
:root[data-theme="dark"] .footer-nav-btn:hover { border-color: #555; }
:root[data-theme="dark"] .site-footer--about {
  background: #141414;
  color: #e8e8e8;
}
/* Footer is dark in both themes, but its text/links are coloured var(--bg) -
   which flips to near-black in dark mode. Force them light. */
:root[data-theme="dark"] .site-footer--about a,
:root[data-theme="dark"] .footer-bottom .footer-mark { color: #e8e8e8; }
:root[data-theme="dark"] .about-defs > div { border-top-color: #333; }
:root[data-theme="dark"] .footer-bottom { border-top-color: #333; }
/* On phones, stack the footer bottom row so the link + email sit under the
   cross-page button (full-width on top). On the homepage the button is absent,
   so the two meta lines just stack on their own. */
@media (max-width: 700px) {
  .footer-bottom {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .footer-bottom .footer-nav-btn { align-self: stretch; text-align: center; }
  .footer-bottom .footer-meta:has(a[href*="github"]) { text-align: right; }
}

/* ---------- ABOUT PAGE ---------- */
.about-block { margin-top: 16px; }
.about-block p { color: var(--muted); max-width: 60ch; line-height: 1.6; margin: 0 0 12px; }
.about-block p:last-child { margin-bottom: 0; }
.about-caps {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin: 0;
  padding: 0;
}
.about-caps > div {
  border-top: 1px solid var(--rule);
  padding: 12px 0;
}
.about-caps dt {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--muted);
  margin-bottom: 2px;
}
.about-caps dd {
  margin: 0;
  font-size: var(--t-small);
  color: var(--fg);
  max-width: 60ch;
  line-height: 1.5;
}
.about-readout { margin-bottom: 0; }
.about-readout th { width: 120px; white-space: nowrap; }
.about-exts {
  display: block;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  word-spacing: 6px;
  text-transform: uppercase;
  color: var(--fg);
  line-height: 2;
}
/* Per-format SEO description under the extension list. Offset anchor targets
   so #fmt-… / #ext-… deep-links don't hide behind the sticky nav. */
.about-fmt-desc {
  display: block;
  margin-top: 5px;
  font-family: var(--font-sans);
  font-size: var(--t-small);
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}
.about-readout tr { scroll-margin-top: 84px; }
.about-ext { scroll-margin-top: 84px; }
.about-formats {
  border-top: 1px solid var(--hairline);
  margin-top: 24px;
  padding-top: 0;
}
.about-formats summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 14px 0;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
.about-formats summary::-webkit-details-marker { display: none; }
.about-formats summary::after {
  content: '+';
  font-size: 14px;
  color: var(--muted);
  transition: transform 0.2s ease;
}
.about-formats[open] summary::after {
  content: '\2212';
}
.about-formats summary:hover { color: var(--accent); }

/* Patch notes */
.patch-entry {
  border-top: 1px solid var(--hairline);
  padding: 16px 0;
}
.patch-entry:first-child { border-top: none; }
.patch-version {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg);
  margin: 0;
}
.patch-date {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 2px 0 8px;
}
.patch-list {
  margin: 0;
  padding-left: 18px;
  font-size: var(--t-small);
  color: var(--muted);
  line-height: 1.6;
}
.patch-list li { padding: 1px 0; }

/* Each patch carries a short codename, shown between the version and the date. */
.patch-name {
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--fg);
  margin: 2px 0 0;
}
.patch-milestone .patch-name { color: var(--accent); }

/* Inline emphasis inside patch notes */
.patch-list strong { color: var(--fg); font-weight: 600; }
.patch-list em { font-style: normal; color: var(--accent); }
.patch-list u { text-decoration-color: var(--accent); text-underline-offset: 2px; }
.patch-list a {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 2px;
}
.patch-list a:hover { color: var(--accent); text-decoration-color: var(--accent); }

/* Changelog "tl;dr" toggle - swaps every patch's bullet list for a short summary,
   and reveals the folded older entries so the whole history reads at a glance. */
.patch-head-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.patch-tldr-toggle {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 3px 8px;
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--fg);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.patch-tldr-toggle:hover { background: var(--fg); color: var(--bg); }
.patch-tldr-toggle.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}
/* The condensed summary sits where the bullet list would be; shown only in tl;dr mode. */
.patch-tldr {
  display: none;
  margin: 0;
  font-size: var(--t-small);
  color: var(--muted);
  line-height: 1.6;
  max-width: 70ch;
}
.tldr-mode .patch-list { display: none; }
.tldr-mode .patch-tldr { display: block; }
/* In tl;dr mode the older entries are force-revealed, so drop the fold's chrome. */
.tldr-mode .about-formats { border-top: none; margin-top: 0; }
.tldr-mode .about-formats > summary { display: none; }

/* Little category tags: New / Fix / Faster */
.patch-tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 9px;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0 5px;
  margin-right: 6px;
  border: 1px solid var(--accent);
  color: var(--accent);
  border-radius: var(--radius);
  vertical-align: 1px;
}
.patch-tag.is-fix { border-color: var(--muted); color: var(--muted); }
.patch-tag.is-faster { border-color: var(--fg); color: var(--fg); }

/* The crowned 1.0 release entry */
.patch-milestone {
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 16px;
  margin: 18px 0;
  background: rgba(var(--accent-rgb), 0.06);
}
.patch-milestone .patch-version {
  color: var(--accent);
  font-size: var(--t-small);
}
.patch-milestone .patch-version::after {
  content: 'Finally complete.';
  margin-left: 8px;
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  vertical-align: middle;
  animation: patchWoo 1.6s ease-in-out infinite;
}
@keyframes patchWoo {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  .patch-milestone .patch-version::after { animation: none; }
}

/* ---------- FOOTER ---------- */
.site-footer {
  border-top: 1px solid var(--hairline);
  padding: 32px var(--pad-x);
  max-width: 1440px;
  margin: 0 auto;
}
.footer-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: var(--t-small);
}
.footer-mark {
  font-weight: 500;
}
.footer-meta {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.footer-meta a { color: inherit; }

/* ---------- QUICKDROP (fields lifted above section 01) ---------- */
.quickdrop {
  padding: 20px var(--pad-x) 0;
  max-width: 1440px;
  margin: 0 auto;
}
/* Replaces the three dropzones once a file is loaded; reloads to a clean page.
   Swiss treatment: a mono, tracked, uppercase label in a sharp-cornered box that
   inverts on hover, with an arrow that nudges forward. */
.analyse-next {
  display: flex;
  align-items: center;
  gap: 14px;
  width: max-content;
  max-width: calc(100% - 2 * var(--pad-x));
  margin: 22px auto;
  padding: 13px 22px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--fg);
  border-radius: 0;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}
.analyse-next::after {
  content: '→';
  font-size: 1.1em;
  letter-spacing: 0;
  transition: transform 0.18s ease;
}
.analyse-next:hover { background: var(--fg); color: var(--bg); }
.analyse-next:hover::after { transform: translateX(5px); }
.analyse-next:active { transform: translateY(1px); }
.analyse-next[hidden] { display: none; }
/* Square down-arrow under "Analyse next file?" - jumps to the first analysed
   section. Same Swiss idiom as .analyse-next (square, hairline, invert hover). */
.scroll-to-data {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0 auto 22px;
  font-size: 1.2em;
  line-height: 1;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--fg);
  border-radius: 0;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
.scroll-to-data::after { content: '\2193'; transition: transform 0.18s ease; }
.scroll-to-data:hover { background: var(--fg); color: var(--bg); }
.scroll-to-data:hover::after { transform: translateY(3px); }
.scroll-to-data:active { transform: translateY(1px); }
.scroll-to-data[hidden] { display: none; }
.quickdrop-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
}
@media (max-width: 700px) {
  .quickdrop-grid { grid-template-columns: 1fr 1fr; }
  .quickdrop-grid > :nth-child(2) { order: 2; grid-column: 1 / -1; }
  .quickdrop-grid > :nth-child(3) { order: 1; }
}
.quickdrop-zone { margin: 0 !important; display: flex; flex-direction: column; }
.quickdrop-zone .anr-dropzone-inner {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Top-align so the icon + heading line up across all three zones regardless
     of how much content (hints/buttons) sits below them. */
  justify-content: flex-start;
  padding: clamp(24px, 4vw, 48px) 18px;
}
.quickdrop-zone .anr-dropzone-inner strong {
  font-size: clamp(16px, 1.8vw, 22px);
  margin: 2px 0 4px;
  color: var(--accent);
}
.quickdrop-zone .anr-drop-icon {
  font-size: clamp(22px, 3.5vw, 34px);
  margin-bottom: 6px;
}
.quickdrop-zone .anr-hint {
  margin-top: 10px !important;
  /* Keep the format list to a single row. If it would wrap to a second line
     (e.g. the photo zone lists both photo and video extensions), truncate the
     overflow with an ellipsis instead - a taller hint would push this zone out
     of line with the other two. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

/* Touch devices can't drag-drop a file, so the zones read "Pick …" instead of
   "Drop …", and the format lists are dropped for a cleaner tap target. The
   "Info" button still opens the full supported-formats list. */
.tap-word { display: none; }
@media (pointer: coarse) {
  .drop-word { display: none; }
  .tap-word { display: inline; }
  /* Photo/video and sound keep their format lists; only the "any file" zone
     hides its list (the Info button already opens the full catalogue). */
  #videoDrop .anr-hint { display: none; }
}

/* Format help button - matches .anr-audio-modes .anr-btn style */
.fmt-help-btn {
  position: absolute;
  bottom: 0;
  right: 0;
  background: var(--bg);
  border: none;
  border-top: 1px solid var(--hairline);
  border-left: 1px solid var(--hairline);
  border-radius: 0;
  font-family: var(--font-sans);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--fg);
  cursor: pointer;
  padding: 11px 8px;
  width: auto;
  z-index: 2;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.2s ease;
}
.fmt-help-btn:hover { background: var(--fg); color: var(--bg); border-top-color: var(--fg); border-left-color: var(--fg); }

/* OCR language picker modal (PDF page OCR; same menu as the image OCR dropdown) */
.anr-ocr-lang {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: rgba(0,0,0,0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.anr-ocr-lang-inner {
  background: var(--bg);
  border: 1px solid var(--hairline);
  max-width: 420px;
  width: 100%;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.anr-ocr-lang-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px 8px;
}
.anr-ocr-lang-head h3 { margin: 0; font-size: var(--t-h3); }
.anr-ocr-lang-list {
  margin: 0 20px;
  padding: 0;
  list-style: none;
  background: var(--bg);
  border: 1px solid var(--hairline);
  max-height: 46vh;
  overflow-y: auto;
}
.anr-ocr-lang-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  align-items: center;
  padding: 12px 20px 20px;
}
.anr-ocr-lang-run { background: var(--fg); color: var(--bg); border-color: var(--fg); }
/* Square "?" button pinned to the bottom-left of the actions row (margin-right
   auto pushes Cancel/Run to the right). Toggles the OCR help panel above it. */
.anr-ocr-lang-help {
  margin-right: auto;
  width: 36px;
  min-width: 36px;
  height: 36px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--hairline);
  border-radius: 0;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.anr-ocr-lang-help:hover { color: var(--fg); border-color: var(--fg); }
.anr-ocr-lang-help.is-active { background: var(--fg); color: var(--bg); border-color: var(--fg); }
/* Occupies the same slot as the language list (it replaces it when toggled). */
.anr-ocr-lang-help-panel {
  margin: 0 20px;
  padding: 14px 16px;
  border: 1px solid var(--hairline);
  background: var(--bg);
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  line-height: 1.7;
  color: var(--muted);
  max-height: 46vh;
  overflow-y: auto;
}
.anr-ocr-lang-help-panel[hidden] { display: none; }
.anr-ocr-lang-help-panel strong { color: var(--fg); text-transform: uppercase; letter-spacing: 0.08em; }
.anr-ocr-lang-help-panel a { color: var(--accent); }
.anr-ocr-lang-remember {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 20px 0;
  font-size: var(--t-tiny);
  letter-spacing: 0.04em;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
/* Square Swiss checkbox to match the custom range control - a hairline box that
   fills with the accent and shows a thin tick when ticked (no native rounding). */
.anr-ocr-lang-remember input {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  width: 15px;
  height: 15px;
  margin: 0;
  border: 1px solid var(--hairline);
  background: var(--bg);
  border-radius: 0;
  cursor: pointer;
  display: inline-grid;
  place-content: center;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.anr-ocr-lang-remember input::before {
  content: '';
  width: 3px;
  height: 7px;
  margin-top: -1px;
  border: solid var(--accent-fg, #fff);
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 0.12s ease;
}
.anr-ocr-lang-remember input:hover { border-color: var(--fg); }
.anr-ocr-lang-remember input:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.anr-ocr-lang-remember input:checked::before { transform: rotate(45deg) scale(1); }
.anr-ocr-lang-remember:hover { color: var(--fg); }
/* "downloaded"/"offline" trained-data languages get an accent tint in the menu. */
.anr-dropdown-item-size.is-downloaded { color: var(--accent); }
.anr-dropdown-item.is-selected .anr-dropdown-item-size.is-downloaded { color: inherit; }

/* Format overlay */
.fmt-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0,0,0,0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.fmt-overlay[hidden] { display: none; }
.fmt-overlay-inner {
  background: var(--bg);
  border: 1px solid var(--hairline);
  max-width: 760px;
  width: 100%;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.fmt-overlay-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px 0;
}
.fmt-overlay-header h3 {
  margin: 0;
  font-size: var(--t-h3);
}
.fmt-overlay-close {
  background: none;
  border: none;
  font-size: 22px;
  color: var(--muted);
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
  transition: color 0.15s ease;
}
.fmt-overlay-close:hover { color: var(--fg); }
.fmt-overlay-search {
  margin: 12px 20px;
  padding: 8px 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  background: var(--surface);
  border: 1px solid var(--hairline);
  color: var(--fg);
  outline: none;
}
.fmt-overlay-search:focus { border-color: var(--accent); }
.fmt-overlay-body {
  padding: 0 20px 20px;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;          /* let the body scroll instead of growing the modal */
}
.fmt-section-label {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg);
  font-weight: 500;
  margin: 26px 0 10px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
}
.fmt-section-note {
  text-transform: none;
  letter-spacing: 0.02em;
  color: var(--muted);
  font-weight: 400;
}
.fmt-section-note::before { content: ' · '; }
/* First section ("Full analysis") needs no divider above it. */
.fmt-section-label:first-child {
  margin-top: 4px;
  padding-top: 0;
  border-top: none;
}
/* Collapsible per-format rows (shared by the overlay and the about page).
   Each row is a native <details class="fmt-item"> revealing its description on
   click. Sharp corners, accent on open, to match the rest of the site. */
.fmt-list { margin: 0; }
.fmt-item {
  border-top: 1px solid var(--hairline);
}
.fmt-item:first-child { border-top: none; }
.fmt-item.is-hidden { display: none; }
.fmt-item-summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 9px 0;
  position: relative;
}
.fmt-item-summary::-webkit-details-marker { display: none; }
.fmt-item-summary::after {
  content: '+';
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--muted);
  flex: none;
}
.fmt-item[open] > .fmt-item-summary::after { content: '\2212'; }
.fmt-item-summary:hover { color: var(--accent); }
.fmt-item-summary:hover .fmt-item-ext { color: var(--accent); }
.fmt-item-label {
  flex: none;
  min-width: 100px;
  font-family: var(--font-sans);
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--fg);
}
.fmt-item-exts {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  word-spacing: 4px;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1.7;
  word-break: normal;
  overflow-wrap: break-word;
}
.fmt-item-ext { scroll-margin-top: 84px; }
.fmt-item[open] > .fmt-item-summary { color: var(--accent); }
.fmt-item-desc {
  padding: 0 0 12px;
  font-family: var(--font-sans);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--muted);
  max-width: 60ch;
  scroll-margin-top: 84px;
}
.fmt-item { scroll-margin-top: 84px; }

/* ---- Category chips (modal filter) ---- */
.fmt-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 20px 12px;
}
.fmt-chip {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 5px 10px;
  border: 1px solid var(--hairline);
  background: var(--bg);
  color: var(--muted);
  cursor: pointer;
  border-radius: 0;
  white-space: nowrap;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.fmt-chip:hover { color: var(--fg); border-color: var(--fg); }
.fmt-chip.is-active { background: var(--fg); color: var(--bg); border-color: var(--fg); }

/* ---- Status line: result count + expand/collapse-all ---- */
.fmt-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 20px 10px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.04em;
  color: var(--muted);
}
.fmt-toggle-all {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.12s ease;
}
.fmt-toggle-all:hover { color: var(--accent); }
.fmt-toggle-all:disabled { opacity: 0.4; cursor: default; }

/* ---- Per-row depth badge (FULL = viewer, ID = identification) ---- */
.fmt-item-badge {
  flex: none;
  margin-left: auto;          /* pushes the badge + the +/- glyph to the right */
  align-self: center;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.4;
  padding: 2px 6px;
  border: 1px solid var(--hairline);
  color: var(--muted);
}
.fmt-item-badge.is-full { color: var(--accent); border-color: var(--accent); }
.fmt-item[open] > .fmt-item-summary .fmt-item-badge.is-id { border-color: var(--fg); color: var(--fg); }

/* ---- Search match highlight ---- */
.fmt-mark {
  background: var(--accent);
  color: var(--accent-fg);
  border-radius: 0;
  padding: 0 1px;
}

/* ---- Empty state ---- */
.fmt-empty {
  margin: 28px 0 8px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.04em;
  color: var(--muted);
}
.fmt-empty[hidden] { display: none; }

/* First *visible* category header drops its divider (JS sets is-first-visible as
   the chip filter hides whole categories). */
.fmt-section-label.is-first-visible {
  margin-top: 4px;
  padding-top: 0;
  border-top: none;
}

/* Mobile: turn the centred modal into a bottom sheet; chips scroll sideways. */
@media (max-width: 700px) {
  .fmt-overlay { align-items: flex-end; padding: 0; }
  .fmt-overlay-inner {
    max-width: 100%;
    max-height: 90vh;
    border-left: none;
    border-right: none;
    border-bottom: none;
  }
  .fmt-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .fmt-chips::-webkit-scrollbar { display: none; }
}

/* Clickable "N supported formats" affordance (dropzone hint + about page). */
.fmt-count-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: var(--hairline);
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
.fmt-count-link:hover { color: var(--accent); text-decoration-color: var(--accent); }
.about-formats-actions { margin: 8px 0 0; }
.fmt-overlay-count {
  font-family: var(--font-mono);
  font-size: 0.62em;
  letter-spacing: 0.04em;
  color: var(--muted);
  vertical-align: middle;
  margin-left: 6px;
}
.quickdrop-zone .anr-audio-modes {
  padding: 0;
  border-top: 1px solid var(--hairline);
  gap: 0;
  transition: border-color 0.2s ease;
}
.quickdrop-zone .anr-audio-modes .anr-btn {
  flex: 1 1 0;
  margin: 0;
  border: none;
  border-right: 1px solid var(--hairline);
  border-radius: 0;
  padding: 11px 8px;
  min-width: 0;
}
.quickdrop-zone .anr-audio-modes .anr-btn:hover { border-right-color: var(--fg); }
.quickdrop-zone .anr-audio-modes .anr-btn:last-child { border-right: none; }

@media (max-width: 420px) {
  .site-nav { padding-left: 14px; padding-right: 14px; }
  .quickdrop { padding-left: 14px; padding-right: 14px; }
  .quickdrop-grid { gap: 12px; }
  .quickdrop-zone .anr-dropzone-inner { padding: 18px 10px; }
  .quickdrop-zone .anr-dropzone-inner strong { font-size: 14px; }
  .quickdrop-zone .anr-drop-icon { font-size: 20px; margin-bottom: 4px; }
}

/* ---------- PAGE-WIDE DROP OVERLAY (until first file) ---------- */
.page-drop {
  position: fixed;
  inset: 0;
  background: rgba(var(--bg-rgb), 0.95);
  z-index: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  animation: anr-fade-in 0.12s ease;
}
.page-drop[hidden] { display: none; }
.page-drop::before {
  content: "";
  position: absolute;
  inset: 16px;
  border: 4px dashed var(--accent);
  pointer-events: none;
}
.page-drop-inner {
  text-align: center;
  padding: 24px;
  max-width: 90vw;
  position: relative;
}
.page-drop-icon {
  font-family: var(--font-mono);
  font-size: clamp(56px, 12vw, 140px);
  font-weight: 300;
  line-height: 1;
  display: block;
  color: var(--accent);
  margin-bottom: 4px;
}
.page-drop-inner strong {
  display: block;
  font-size: clamp(28px, 6vw, 64px);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 8px 0;
  color: var(--fg);
}
.page-drop-inner p {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: clamp(11px, 1.6vw, 14px);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 8px 0 0;
}
@keyframes anr-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ---------- META-COLUMN SLOTS ---------- */
.section-meta-slot { margin-top: 18px; }
.section-meta-slot:empty { display: none; }
.section-meta-slot .anr-card { margin: 0; }
.section-meta-slot .anr-controls {
  padding: 10px 12px;
  gap: 6px;
  flex-direction: column;
  align-items: stretch;
  border-bottom: 1px solid var(--hairline);
}
.section-meta-slot .anr-control {
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
}
.section-meta-slot .anr-control select,
.section-meta-slot .anr-dropdown {
  width: 100%;
}
.section-meta-slot .anr-control .anr-btn {
  width: 100%;
}
.section-meta-slot .anr-ocr-text { font-size: 12px; max-height: 220px; margin-top: 14px; }
/* Keep the 2:1 ratio in the sidebar too - width drives the height there. */

.section-meta-preview {
  border: 1px solid var(--hairline);
  background: var(--surface);
  padding: 6px;
}
.anr-preview-img-wrap {
  position: relative;
  overflow: hidden;
}
/* Bottom-right affordance signalling the thumbnail expands to a lightbox.
   pointer-events:none so it never intercepts the image's click. */
.anr-preview-img-wrap::after {
  content: "";
  position: absolute;
  bottom: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  background: rgba(0, 0, 0, 0.55) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 9V4h5M15 4h5v5M4 15v5h5M20 15v5h-5'/%3E%3C/svg%3E") center / 13px 13px no-repeat;
  border: 1px solid var(--border-on-dark);
  opacity: 0.85;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.anr-preview-img-wrap:hover::after { opacity: 1; }
.anr-checkerboard {
  background: repeating-conic-gradient(#d0d0d0 0% 25%, #fff 0% 50%) 0 0 / 16px 16px;
}
:root[data-theme="dark"] .anr-checkerboard {
  background: repeating-conic-gradient(#2a2a2a 0% 25%, #141414 0% 50%) 0 0 / 16px 16px;
}
.section-meta-preview img {
  display: block;
  width: 100%;
  max-height: clamp(160px, 28vh, 260px);
  object-fit: contain;
  background: var(--media-bg);
  cursor: zoom-in;
}
.section-meta-preview-caption {
  margin: 8px 4px 2px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  word-break: break-word;
  line-height: 1.4;
}
.anr-raw-warning {
  margin: 6px 4px 0;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  color: var(--accent);
  letter-spacing: 0.04em;
  line-height: 1.4;
  opacity: 0.8;
}
/* "Import XMP settings" button under the thumbnail (RAW files only). */
.anr-raw-xmp-import { margin-top: 8px; text-align: center; }

/* On smaller viewports, meta column already drops below section-content; reorder so
   the preview thumb stays compact and the OCR/histogram sit clearly below it */
@media (max-width: 900px) {
  .section-meta-slot { margin-top: 16px; }
  .section-meta-preview img { max-height: 280px; }
  #videoPreview { display: none; }
}
@media (max-width: 700px) {
  .section-meta { display: block; }
  .section-meta-slot { max-width: 100%; }
}

/* ---------- LIGHTBOX ---------- */
.lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  z-index: 1000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 12px;
  padding-bottom: 5vh;
  cursor: zoom-out;
  -webkit-tap-highlight-color: transparent;
}
.lightbox:not([hidden]) { display: flex; }
.lightbox img {
  width: 100%;
  height: 100%;
  object-fit: fill;
  display: block;
  cursor: default;
  user-select: none;
  -webkit-user-drag: none;
}
.lightbox-close {
  position: fixed;
  top: 16px; right: 16px;
  z-index: 10;
  background: transparent;
  border: 1px solid var(--on-dark);
  color: var(--on-dark);
  padding: 10px 14px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  min-height: 40px;
  min-width: 40px;
  transition: background 0.12s ease, color 0.12s ease;
}
.lightbox-close:hover { background: var(--on-dark); color: var(--media-bg); }
.lightbox-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  max-height: 100%;
  overflow: hidden;
}
.lightbox-img-wrap {
  position: relative;
}
.lightbox-peaking {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 3;
}
.lightbox-peaking[hidden] { display: none; }
.lightbox-focus-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  image-rendering: pixelated;
  pointer-events: none;
}
.lightbox-focus-map[hidden] { display: none; }
.lightbox-focus-dot {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--on-dark);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.4), 0 2px 6px rgba(0,0,0,0.5);
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 5;
}
.lightbox-focus-dot[hidden] { display: none; }
.lightbox-toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 8px;
}
.lightbox-toolbar:empty { display: none; }
.lightbox-tool-btn {
  background: transparent;
  border: 1px solid var(--border-on-dark-strong);
  color: rgba(255,255,255,0.8);
  padding: 8px 14px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.lightbox-tool-btn:hover {
  background: var(--border-on-dark);
  color: var(--on-dark);
}
.lightbox-tool-btn.is-active {
  background: var(--on-dark);
  color: var(--media-bg);
  border-color: var(--on-dark);
}
.lightbox-meta {
  position: fixed;
  bottom: 16px; left: 50%;
  transform: translateX(-50%);
  color: rgba(255, 255, 255, 0.78);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  max-width: 90%;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 6px 12px;
  background: rgba(0,0,0,0.4);
}

/* ---------- UNKNOWN FILE RESULTS ---------- */
.anr-unknown-results:not([hidden]) {
  padding: 36px var(--pad-x) 40px;
  border-top: 1px solid var(--hairline);     /* heavy rule above the readout, matching the nav */
  border-bottom: 1px solid var(--hairline);
  max-width: 1440px;
  margin: 0 auto;
  background: var(--bg);
  scroll-margin-top: var(--nav-offset);
}
.anr-unknown-dump {
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  padding: 14px;
  white-space: pre;
  overflow-x: auto;
  margin: 14px 0;
  line-height: 1.55;
}

/* ---------- NAV FLASH (E6) ---------- */
@keyframes anr-nav-flash {
  0%   { background: var(--accent); color: var(--accent-fg); }
  100% { background: transparent;   color: var(--fg); }
}
.nav-link.is-flash {
  animation: anr-nav-flash 0.6s ease-out;
}
.nav-link.is-active.is-flash {
  animation: none;
}

/* ---------- DARK MODE (E1) ---------- */
:root[data-theme="dark"] {
  --bg:        #0a0a0a;
  --fg:        #e8e8e8;
  --muted:     #888;
  --hairline:  #333;
  --rule:      #262626;
  --surface:   #141414;
  --accent:    #ff3347;
  --accent-fg: #ffffff;
  --accent-rgb: 255, 51, 71;
  --bg-rgb:     10, 10, 10;
  --shadow-color: rgba(0, 0, 0, 0.6);
}
:root[data-theme="dark"] .anr-swatch span {
  background: var(--bg);
}

.dark-toggle {
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 8px;
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--fg);
  cursor: pointer;
  white-space: nowrap;
}
.dark-toggle:hover {
  background: var(--fg);
  color: var(--bg);
}

/* ---------- CUSTOM DROPDOWN ---------- */
.anr-dropdown {
  position: relative;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  user-select: none;
}
.anr-dropdown-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 8px;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--hairline);
  cursor: pointer;
  white-space: nowrap;
  min-width: 160px;
  transition: border-color 0.12s ease;
}
.anr-dropdown-trigger:hover:not(.is-disabled) { border-color: var(--fg); }
.anr-dropdown-trigger::after {
  content: '\25BE';
  font-size: 0.75em;
  opacity: 0.5;
}
.anr-dropdown-trigger.is-disabled {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}
.anr-dropdown-list {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 100;
  max-height: 260px;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--hairline);
  border-top: none;
  margin: 0;
  padding: 0;
  list-style: none;
}
.anr-dropdown.is-open .anr-dropdown-list { display: block; }
.anr-dropdown-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 8px;
  cursor: pointer;
  white-space: nowrap;
}
.anr-dropdown-item:hover { background: var(--hairline); }
.anr-dropdown-item.is-selected { background: var(--fg); color: var(--bg); }
.anr-dropdown-item-size {
  margin-left: auto;
  color: var(--muted);
  font-size: 0.85em;
}
.anr-dropdown-item.is-selected .anr-dropdown-item-size {
  color: var(--muted);
}

/* ---------- MOBILE TOUCH-TARGET POLISH ---------- */
@media (max-width: 700px) {
  .anr-btn, .anr-fs-btn { min-height: 40px; padding: 10px 14px; }
  .anr-toggle button { min-height: 36px; padding: 8px 12px; }
  .anr-control select { min-height: 36px; padding: 6px 8px; }
  /* Tighten the nav so home + 3 links + search fit on narrow phones (~360px)
     without the search button overflowing off the right edge. */
  .site-nav {
    display: flex;
    padding-left: 14px; padding-right: 14px;
    /* Keep the bar pinned while scrolling on phones. Re-assert sticky and drop
       the auto side-margins (which can break position:sticky on iOS Safari);
       full-bleed on mobile so no centering margins are involved anyway. */
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    z-index: 30;
    margin-left: 0;
    margin-right: 0;
    max-width: none;
  }
  .nav-link { flex: 1 1 0; padding: 14px 4px; gap: 6px; min-width: 0; }
  .site-about-link { min-height: 36px; display: inline-flex; align-items: center; }
  .nav-search {}
  .nav-search.is-open .nav-search-btn { display: block; }
  .nav-search.is-open .nav-search-input,
  .nav-search.is-open .nav-search-arrow { display: none; }
  /* About page: drop the search control on mobile so the section links get the
     full nav width. (The nav is a sibling of main.about-page, so :has() on the
     body is used to detect the page.) */
  body:has(.about-page) .nav-search { display: none; }
  /* Hiding search removes the 48px-tall button that otherwise sets the bar's
     height, so the links alone would make the nav noticeably shorter. Pad the
     links to keep the about-page nav the same height as the main one. */
  body:has(.about-page) .nav-link { padding-top: 16px; padding-bottom: 16px; }
}

/* ---------- Confirmation modal (mobile upload guard) ---------- */
/* Built in app.js by anrConfirm(). Swiss styling: flat bg, single hard border,
   monospace kicker/buttons, accent on the primary action. */
.anr-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  transition: opacity 0.18s ease;
}
.anr-modal.is-open { opacity: 1; }
.anr-modal-card {
  width: 100%;
  max-width: 360px;
  background: var(--bg);
  border: 1px solid var(--hairline);
  padding: 24px;
  transform: translateY(8px);
  transition: transform 0.18s ease;
}
.anr-modal.is-open .anr-modal-card { transform: none; }
.anr-modal-kicker {
  margin: 0 0 12px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
}
.anr-modal-title {
  margin: 0 0 22px;
  font-size: var(--t-body);
  line-height: 1.35;
  color: var(--fg);
}
.anr-modal-actions { display: flex; gap: 10px; }
.anr-modal-btn {
  flex: 1;
  padding: 12px 14px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  cursor: pointer;
  border: 1px solid var(--hairline);
  background: var(--bg);
  color: var(--fg);
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.anr-modal-cancel:hover { background: var(--surface); }
.anr-modal-ok { background: var(--fg); color: var(--bg); }
.anr-modal-ok:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }

/* ---------- Scene change detection (video) ---------- */
.anr-scene-timeline {
  position: relative;
  height: 24px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  margin-bottom: 14px;
}
.anr-scene-marker {
  position: absolute;
  top: 2px;
  bottom: 2px;
  width: 2px;
  background: var(--accent);
  cursor: pointer;
}
.anr-scene-details { margin-top: 4px; }
.anr-scene-details summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  padding: 6px 0;
}
.anr-scene-details summary:hover { color: var(--accent); }
.anr-scene-details[open] summary { color: var(--fg); margin-bottom: 10px; }
.anr-scene-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.anr-scene-thumb { cursor: pointer; text-align: center; }
.anr-scene-thumb img {
  width: 160px;
  height: 90px;
  object-fit: cover;
  display: block;
  border: 1px solid var(--hairline);
}
.anr-scene-thumb:hover img { border-color: var(--accent); }
.anr-scene-meta {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-top: 3px;
}

/* ---------- UTILITY / REFACTOR CLASSES ---------- */
.is-hidden { display: none !important; }

/* Scrollable <pre> blocks (formerly inline max-height/overflow) */
.anr-pre-scroll    { max-height: 500px; overflow: auto; }
.anr-pre-scroll-sm { max-height: 300px; overflow: auto; }

/* Collapsible file tree (folders + archives) */
.anr-tree {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  line-height: 1.5;
  max-height: 560px;
  overflow: auto;
}
/* Reset the global `details` styling (border-top, padding, margin, +/- marker)
   so it doesn't bleed into the tree's folder rows. */
.anr-tree-dir {
  border-top: none;
  padding: 0;
  margin: 0;
}
.anr-tree-dir > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 5px 6px;
  user-select: none;
  font-size: var(--t-small);
  letter-spacing: 0;
  text-transform: none;
  transition: background 0.1s ease, color 0.1s ease;
}
.anr-tree-dir > summary::-webkit-details-marker { display: none; }
.anr-tree-dir > summary::after { content: none; }
.anr-tree-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  flex-shrink: 0;
  color: var(--muted);
  font-size: 10px;
  transition: transform 0.12s ease, color 0.12s ease;
}
.anr-tree-dir[open] > summary > .anr-tree-icon { transform: rotate(90deg); }
.anr-tree-dir > summary:hover { background: var(--surface); color: var(--accent); }
.anr-tree-dir > summary:hover .anr-tree-icon { color: var(--accent); }
.anr-tree-dir > summary .anr-tree-name { font-weight: 500; }
.anr-tree-children {
  margin-left: 11px;
  padding-left: 12px;
  border-left: 1px solid var(--rule);
}
.anr-tree-file {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px;
  transition: background 0.1s ease, color 0.1s ease;
}
.anr-tree-lead {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  flex-shrink: 0;
}
.anr-tree-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius);
  flex-shrink: 0;
}
.anr-tree-file:hover { background: var(--surface); }
.anr-tree-name { word-break: break-all; flex: 1 1 auto; min-width: 0; }
.anr-tree-meta {
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
  margin-left: auto;
  font-size: var(--t-tiny);
  font-variant-numeric: tabular-nums;
}
.anr-tree-file.is-clickable { cursor: pointer; }
.anr-tree-file.is-clickable:hover { background: var(--fg); color: var(--bg); }
.anr-tree-file.is-clickable:hover .anr-tree-meta { color: var(--bg); }
.anr-tree-copy {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  padding: 2px 4px;
  opacity: 0;
  transition: opacity 0.1s ease, color 0.1s ease;
}
.anr-tree-file:hover .anr-tree-copy { opacity: 1; }
.anr-tree-copy:hover { color: var(--accent); }
.anr-tree-file.is-clickable:hover .anr-tree-copy { color: var(--bg); }
.anr-tree-file.is-clickable:hover .anr-tree-copy:hover { color: var(--accent); }

/* Treemap + folder/archive visuals */
.anr-treemap-wrap { position: relative; }
.anr-treemap-wrap canvas { display: block; width: 100%; }
.anr-treemap-tooltip {
  position: absolute; pointer-events: none; z-index: 10;
  font-family: var(--font-mono); font-size: var(--t-tiny);
  background: var(--bg); border: 1px solid var(--hairline);
  padding: 6px 10px; max-width: 70%;
  opacity: 0; transition: opacity 0.1s;
}
.anr-treemap-tooltip.is-visible { opacity: 1; }
.anr-treemap-tooltip .anr-tt-name { word-break: break-all; color: var(--fg); }
.anr-treemap-tooltip .anr-tt-meta { color: var(--muted); margin-top: 2px; text-transform: uppercase; letter-spacing: 0.05em; }
.anr-treemap-breadcrumb {
  font-family: var(--font-mono); font-size: var(--t-tiny);
  letter-spacing: 0.05em;
  padding: 0 0 8px; margin-bottom: 8px;
  border-bottom: 1px solid var(--rule);
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
}
.anr-treemap-breadcrumb button {
  background: none; border: none; color: var(--muted);
  cursor: pointer; font-family: inherit; font-size: inherit;
  letter-spacing: inherit;
  padding: 0; text-transform: uppercase;
  transition: color 0.12s ease;
}
.anr-treemap-breadcrumb button:hover { color: var(--accent); }
.anr-crumb-sep { color: var(--muted); opacity: 0.5; }
.anr-crumb-current { color: var(--fg); text-transform: uppercase; }
.anr-treemap-status {
  font-family: var(--font-mono); font-size: var(--t-tiny);
  color: var(--muted); letter-spacing: 0.03em;
  padding: 8px 0 0; margin-top: 8px;
  border-top: 1px solid var(--rule);
  word-break: break-all;
}
.anr-treemap-status .anr-status-name { color: var(--fg); }
.anr-treemap-content { margin-top: 14px; }
/* Cursor confirm popup (treemap file click) */
.anr-treemap-menu {
  position: fixed; z-index: 1000;
  background: var(--bg); border: 1px solid var(--hairline);
  font-family: var(--font-mono); font-size: var(--t-tiny);
  padding: 10px 11px; min-width: 150px; max-width: 260px;
}
/* Name on the left, a compact Copy button pinned top-right on the same line.
   min-width:0 + the gap guarantee the long name wraps under itself and never
   overlaps the button. */
.anr-tm-header { display: flex; align-items: flex-start; gap: 10px; }
.anr-tm-name { color: var(--fg); font-weight: 500; word-break: break-all; flex: 1 1 auto; min-width: 0; }
.anr-tm-copy { flex: 0 0 auto; padding: 2px 6px; font-size: 9px; }
.anr-tm-meta { color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; margin-top: 2px; }
.anr-tm-q { color: var(--fg); margin: 9px 0 8px; }
.anr-tm-actions { display: flex; gap: 8px; justify-content: flex-end; }
.anr-tm-btn {
  font-family: var(--font-mono); font-size: var(--t-tiny);
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 5px 11px; border: 1px solid var(--hairline);
  background: var(--bg); color: var(--fg); cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.anr-tm-btn:hover { background: var(--fg); color: var(--bg); }
.anr-tm-btn-ok { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }
.anr-tm-btn-ok:hover { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.anr-treemap-legend {
  display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center;
  margin-left: auto;
}
.anr-legend-item {
  font-family: var(--font-mono); font-size: var(--t-tiny);
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted); display: inline-flex; align-items: center; gap: 5px;
}
.anr-legend-swatch {
  display: inline-block; width: 8px; height: 8px;
  flex-shrink: 0;
}
/* File types show-more */
.anr-ext-more {
  border-top: 1px solid var(--hairline);
  margin-top: 0;
  padding-top: 0;
}
.anr-ext-more summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 10px 0;
  list-style: none;
  display: flex; align-items: center; gap: 6px;
  user-select: none;
}
.anr-ext-more summary::-webkit-details-marker { display: none; }
.anr-ext-more summary::after {
  content: '+'; font-size: 13px; color: var(--muted);
  transition: color 0.15s ease;
}
.anr-ext-more[open] summary::after { content: '\2212'; }
.anr-ext-more summary:hover { color: var(--accent); }
.anr-ext-more summary:hover::after { color: var(--accent); }
/* Controls bar for treemap/tree toggle */
.anr-view-controls {
  display: flex; flex-wrap: wrap; gap: 10px 22px;
  align-items: center;
  padding: 0 0 14px;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 14px;
}

/* SVG inspector */
.anr-svg-preview {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 12px;
  overflow: auto;
  max-height: 500px;
  background: repeating-conic-gradient(var(--surface) 0% 25%, var(--bg) 0% 50%) 50% / 16px 16px;
}
.anr-svg-error { color: var(--accent); }
.anr-svg-palette { display: flex; flex-wrap: wrap; gap: 6px; }
.anr-svg-swatch-item { text-align: center; }
.anr-svg-swatch {
  width: 32px;
  height: 32px;
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
  cursor: pointer;
}
.anr-svg-swatch-label {
  font-size: 10px;
  max-width: 50px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-top: 2px;
}

/* STL 3D viewer */
.anr-stl-viewport {
  width: 100%;
  height: 440px;
  border: 1px solid var(--hairline);
  background: var(--media-bg);
  position: relative;
  overflow: hidden;
}
.anr-stl-viewport:fullscreen { height: 100vh; }
.anr-stl-canvas { display: block; touch-action: none; cursor: grab; }
.anr-stl-canvas:active { cursor: grabbing; }

/* XLSX spreadsheet viewer */
.anr-xlsx-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 10px; }
.anr-xlsx-tab {
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 4px 12px;
  background: var(--bg);
  border: 1px solid var(--hairline);
  cursor: pointer;
  color: var(--fg);
}
.anr-xlsx-tab.is-active { background: var(--fg); color: var(--bg); }
.anr-xlsx-table-wrap { overflow: auto; max-height: 540px; border: 1px solid var(--hairline); }
.anr-xlsx-table { border-collapse: collapse; font-size: 12px; font-family: var(--font-mono); }
.anr-xlsx-table th, .anr-xlsx-table td {
  border: 1px solid var(--rule);
  padding: 3px 8px;
  text-align: left;
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.anr-xlsx-table th { background: var(--surface); position: sticky; top: 0; font-weight: 600; }
.anr-xlsx-rownum, .anr-xlsx-corner { background: var(--surface); position: sticky; left: 0; color: var(--muted); }

/* EPUB reader */
.anr-epub-nav { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.anr-epub-viewport {
  border: 1px solid var(--rule);
  padding: 24px;
  max-height: 600px;
  overflow: auto;
  line-height: 1.6;
}
.anr-epub-content img { max-width: 100%; height: auto; }
.anr-epub-content h1, .anr-epub-content h2, .anr-epub-content h3 { margin: 1em 0 0.4em; }
.anr-epub-content p { margin: 0 0 0.8em; }

/* PPTX slide viewer */
.anr-pptx-slide {
  position: relative;
  border: 1px solid var(--hairline);
  background: var(--bg);
  margin: 0 0 18px;
  padding: 32px 36px;
  overflow: hidden;
}
.anr-pptx-num {
  position: absolute;
  top: 8px;
  right: 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
}
.anr-pptx-title { font-size: clamp(20px, 3vw, 30px); font-weight: 600; margin-bottom: 14px; }
.anr-pptx-title p { margin: 0 0 4px; }
.anr-pptx-body { font-size: 15px; line-height: 1.5; }
.anr-pptx-body p { margin: 0 0 6px; }
.anr-pptx-img { max-width: 60%; height: auto; margin: 10px 0; border: 1px solid var(--rule); }
.anr-pptx-notes { margin-top: 14px; font-size: 13px; color: var(--muted); }
.anr-pptx-notes summary { cursor: pointer; }

/* CSV / TSV data table */
.anr-table-wrap {
  overflow: auto;
  max-height: 500px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}
.anr-table-data {
  width: auto;
  min-width: 100%;
  white-space: nowrap;
}
.anr-table-sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  background: var(--bg);
  z-index: 1;
}

/* JSON / XML syntax highlighting */
.anr-syn-key     { font-weight: 700; }
.anr-syn-str     { color: #5a9e5a; }
.anr-syn-num     { color: #5b9fd6; }
.anr-syn-kw      { color: #e89a2e; font-weight: 700; }
.anr-syn-comment { color: var(--muted); }
.anr-syn-tag     { color: #5b9fd6; font-weight: 700; }
.anr-syn-attr    { color: #e89a2e; }
.anr-syn-error   { color: var(--accent); margin: 4px 0; }
.anr-fmt-summary { cursor: pointer; font-weight: 700; margin: 8px 0; }
.anr-hash-out    { word-break: break-all; font-size: 12px; margin: 4px 0 0; }

/* Waveform selection overlay */
.anr-wave-wrap { position: relative; display: inline-block; width: 100%; }
.anr-wave-overlay {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  background: transparent;
}
.anr-sel-controls { gap: 8px; margin-top: 6px; }
.anr-sel-label { font-size: 0.85em; opacity: 0.8; }
.anr-btn-sm { font-size: 0.82em; padding: 3px 10px; }

/* Hidden video probe for off-screen frame capture. Kept renderable (NOT
   display:none) and in the DOM so the browser gives it a decode surface. iOS
   Safari often won't decode something this small/hidden; video.js handles that
   by falling back to a visible player. */
.anr-video-probe {
  position: fixed;
  left: 0;
  top: 0;
  width: 1px;
  height: 1px;
  opacity: 0.01;
  pointer-events: none;
  z-index: -1;
}
/* Non-blocking "Analysing…" badge over the video player while scene detection
   runs in the background. pointer-events:none keeps the player interactive. */
.anr-video-analysing {
  position: absolute;
  top: 52px;
  right: 14px;
  z-index: 2;
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  font-family: var(--font-mono);
  font-size: var(--t-tiny);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-dark);
  background: rgba(0, 0, 0, 0.62);
  border: 1px solid var(--border-on-dark);
  backdrop-filter: blur(2px);
}
.anr-video-analysing::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: anr-blink 1s steps(2, end) infinite;
}

/* ---------- MOBILE LAYOUT TUNING ---------- */
@media (max-width: 700px) {
  /* Result content lines up with the dropzones (14px from the screen edge)
     instead of being pushed in by the section-content box. The cards are
     transparent, so the section-content frame is what we pull in. */
  .section .grid { padding-left: 14px; padding-right: 14px; }
  /* The frame sits 14px from the screen edge (via the grid padding); a small
     inner gutter keeps text from touching its border. */
  .section-content {
    padding-left: 14px;
    padding-right: 14px;
  }
  .anr-unknown-results:not([hidden]) { padding-left: 14px; padding-right: 14px; }

  /* Spectrogram settings (segmented groups): stack the groups vertically, each
     separated by a top hairline, and pack each group's controls into a tidy
     2-up grid so nothing overlaps and they take far less vertical space. */
  .anr-spec-card .anr-controls {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .anr-spec-card .anr-control-group {
    flex-direction: column;
    align-self: stretch;
    gap: 8px;
    padding: 12px 0;
    border-left: none;
    border-top: 1px solid var(--hairline);
  }
  .anr-spec-card .anr-control-group:first-child { border-top: none; padding-top: 0; }
  .anr-spec-card .anr-control-group:last-child  { padding-bottom: 0; }
  .anr-spec-card .anr-control-group-items {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px 12px;
    align-items: center;
  }
  .anr-spec-card .anr-control { min-width: 0; }
  .anr-spec-card .anr-control > label { white-space: nowrap; flex: 0 0 auto; }
  /* select/range flex into the space left after the label - no fixed width,
     so the label and field never overlap in a narrow cell. */
  .anr-spec-card .anr-control select { flex: 1 1 auto; min-width: 0; }
  .anr-spec-card .anr-control input[type="range"] { flex: 1 1 auto; width: auto; min-width: 0; }
  .anr-spec-card .anr-control .anr-toggle { display: flex; flex: 1 1 auto; }
  .anr-spec-card .anr-control .anr-toggle button { flex: 1 1 auto; }
  /* The Axis toggle and the Sensitivity slider are the widest controls - give
     each its own full-width cell so the slider has room to drag and the label
     can't crush it to zero width. */
  .anr-spec-card .anr-control:has(.anr-toggle),
  .anr-spec-card .anr-control:has(input[type="range"]) { grid-column: 1 / -1; }
  .anr-spec-card .anr-control:has(input[type="range"]) input[type="range"] { width: 100%; }
  .anr-spec-card .anr-control .anr-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1 1 auto;
    width: 100%;
  }
  /* Play/pause spans the full width on mobile so it reads as part of the
     control block instead of a lone floating button. */
  .anr-spec-card .anr-spec-play { width: 100%; }
}

/* ---------- GRABBABLE PLAYHEAD + SPECTROGRAM TRANSPORT ---------- */
/* A wider invisible hit-area around the 1px line so it's easy to grab and drag;
   the visible line stays 1px via the ::before. */
.anr-playhead.is-grabbable {
  width: 13px;
  margin-left: -6px;
  background: transparent;
  pointer-events: auto;
  cursor: col-resize;
}
.anr-playhead.is-grabbable::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--on-dark);
}

.anr-spec-transport {
  margin-top: 10px;
}
.anr-spec-play { min-width: 120px; }

/* ---------- HISTOGRAM AXIS MARKINGS ---------- */
.anr-hist-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.04em;
  margin-top: 4px;
}
.anr-hist-caption {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-align: center;
  margin: 6px 0 0;
}

/* ---------- RENDERED MARKDOWN ---------- */
.anr-md-body {
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.65;
  color: var(--fg);
  max-width: 72ch;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.anr-md-body > :first-child { margin-top: 0; }
.anr-md-body > :last-child { margin-bottom: 0; }

.anr-md-h { font-family: var(--font-sans); font-weight: 600; line-height: 1.25; margin: 1.6em 0 0.6em; }
.anr-md-h1 { font-size: 1.8em; padding-bottom: 0.3em; border-bottom: 1px solid var(--rule); }
.anr-md-h2 { font-size: 1.45em; padding-bottom: 0.25em; border-bottom: 1px solid var(--rule); }
.anr-md-h3 { font-size: 1.2em; }
.anr-md-h4 { font-size: 1.05em; }
.anr-md-h5 { font-size: 0.95em; }
.anr-md-h6 { font-size: 0.9em; color: var(--muted); }

.anr-md-p { margin: 0 0 1em; }

.anr-md-link { color: var(--accent); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); }
.anr-md-link:hover { border-bottom-color: var(--accent); }

.anr-md-body strong { font-weight: 700; }
.anr-md-body em { font-style: italic; }
.anr-md-body del { opacity: 0.65; }

.anr-md-list { margin: 0 0 1em; padding-left: 1.6em; }
.anr-md-list li { margin: 0.25em 0; }
.anr-md-list .anr-md-list { margin-bottom: 0; }
li.anr-md-task { list-style: none; margin-left: -1.4em; }
li.anr-md-task input { margin-right: 0.5em; vertical-align: middle; }

.anr-md-quote {
  margin: 0 0 1em;
  padding: 0.2em 1em;
  border-left: 3px solid var(--rule);
  color: var(--muted);
}
.anr-md-quote > :last-child { margin-bottom: 0; }

.anr-md-hr { border: none; border-top: 1px solid var(--rule); margin: 1.8em 0; }

.anr-md-icode {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.1em 0.35em;
}
.anr-md-codewrap { position: relative; margin: 0 0 1em; }
.anr-md-codelang {
  position: absolute;
  top: 0; right: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-top: none; border-right: none;
  padding: 2px 8px;
}
.anr-md-code {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  line-height: 1.5;
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: 14px 16px;
  margin: 0;
  overflow: auto;
}
.anr-md-code code { background: none; border: none; padding: 0; font-size: inherit; }

.anr-md-img { max-width: 100%; height: auto; display: block; margin: 1em 0; border: 1px solid var(--rule); }

.anr-md-tablewrap { overflow-x: auto; margin: 0 0 1em; }
.anr-md-table { border-collapse: collapse; font-size: var(--t-small); width: auto; }
.anr-md-table th, .anr-md-table td { border: 1px solid var(--rule); padding: 6px 12px; text-align: left; }
.anr-md-table th { background: var(--surface); font-weight: 600; }
.anr-md-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--surface) 55%, transparent); }
