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

:root {
  --bg: #000000;
  --panel: #000000;
  --card: #000000;
  --text: #f0efe9;
  --muted: #9a9aa4;
  --line: #2e2e36;
  --accent: #41FDFE;   /* fallback; the seed sets this at runtime */
  --fs: 12px;   /* one type size for the whole UI */
}

[data-theme="light"] {
  --bg: #ffffff;
  --panel: #ffffff;
  --card: #ffffff;
  --text: #111111;
  --muted: #77777f;
  --line: #d9d9de;
  --accent: #41FDFE;
}

/* Light theme flips the glyph ink and its background-coloured paints */
[data-theme="light"] svg [fill="#ffffff"] { fill: #000000; }
[data-theme="light"] svg [stroke="#ffffff"] { stroke: #000000; }
[data-theme="light"] svg [fill="#000000"] { fill: #ffffff; }
[data-theme="light"] svg [stroke="#000000"] { stroke: #ffffff; }

/* One face, one size, sentence case, normal spacing — everywhere.
   The face itself is the freshly generated font (set via --ui-font). */
body,
button,
input,
select,
output,
label,
h2 {
  font-family: var(--ui-font, Helvetica, "Helvetica Neue", Arial, sans-serif);
  font-size: var(--fs);
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
}

body {
  background: var(--bg);
  color: var(--text);
  padding: 14px;
  display: flex;
  align-items: flex-start;
  gap: 18px;
}

/* Crossfade the UI palette when a new seed lands. The specimen re-renders
   crisply on its own, so only the persistent chrome needs to fade. */
body,
.controls, .credits, .credit-label,
.control-group label, .metric-row span,
input[type="text"], input[type="number"], select {
  transition: background-color 0.45s ease, border-color 0.45s ease, color 0.45s ease;
}

/* ---------- Controls: left sidebar module (compact) ---------- */
header {
  width: 208px;
  flex-shrink: 0;
  position: sticky;
  top: 14px;
  height: calc(100vh - 28px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

/* Credit hugging the bottom of the right column */
.credits {
  margin-top: auto;
  padding: 10px 0;
  border: none;
  background: transparent;   /* reveal the body (same colour) so it fades as one surface on reload */
  color: var(--muted);
  flex-shrink: 0;
}
.credits div + div { margin-top: 1.4em; }   /* full blank line between the two credit groups */
/* Version + Last updated share a row, two columns */
.credit-cols { display: flex; gap: 16px; }
.credit-cols > div { flex: 1; }
.credit-cols > div + div { margin-top: 0; }

/* Full line break after the Size slider (before the metrics inputs) */
.control-group:has(.metric-row) { margin-top: 14px; }
.credit-label {
  display: block;
  color: var(--muted);
  margin-bottom: 2px;
}
.credits a {
  color: var(--text);
  text-decoration: none;
}
.credits a:hover { color: var(--accent); }

/* Icon theme toggle + fullscreen */
.theme-row { display: flex; gap: 4px; }
.icon-btn {
  padding: 4px 8px;
  display: flex;
  align-items: center;
  color: var(--muted);
}
.icon-btn.on {
  color: var(--accent);
  border-color: var(--accent);
}
.icon-btn.on:hover,
.icon-btn.on:active { color: var(--bg); }

main {
  flex: 1;
  min-width: 0;
  position: relative;
  z-index: 1;   /* super-wide glyphs overflow *over* the sticky sidebars */
}

.controls {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 7px;
  background: transparent;   /* was var(--panel); reveal the body so it fades as one surface */
  border: none;
  padding: 0 0 8px;
  margin-bottom: 8px;
  flex-shrink: 0;
}

.control-group select,
.control-group input[type="text"] {
  width: 100%;
}

/* Mobile chrome: hidden on desktop */
#mobile-bar { display: none; }
.drawer, .drawer-backdrop { display: none; }
#preview-typer { display: none; }   /* mobile-only tap-to-type overlay */

@media (max-width: 900px) {
  html, body { overflow-x: hidden; }
  body { display: block; padding: 0; gap: 0; }
  /* Wide glyphs scroll inside the specimen, never stretching the page */
  main { overflow-x: auto; }
  #preview, .glyph-grid { max-width: 100%; }

  /* Pinned top bar: menu button + seed + Reload */
  #mobile-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    position: sticky;
    top: 0;
    z-index: 70;
    padding: 8px 12px;
    background: var(--bg);
  }
  #mobile-bar .control-group { flex: 0 0 auto; min-width: 0; margin: 0; }
  #mobile-bar .control-group > label { display: none; }
  #mobile-bar .seed-row { display: flex; gap: 6px; width: auto; align-items: stretch; }
  #mobile-bar .seed-row > input { flex: 0 0 auto; width: 120px; min-width: 0; }
  #mobile-bar .seed-row > button { flex: 0 0 auto; width: 76px; min-width: 0; white-space: nowrap; }
  /* Menu icon matches the shorter button height (Reload / the drawer buttons
     are 24px; its 18px SVG would otherwise make it taller). Fixed height with
     the icon centred; pushes the seed + Reload cluster to the right. */
  #mobile-bar #menu-btn {
    flex-shrink: 0;
    width: 44px;
    height: 24px;
    box-sizing: border-box;
    padding: 0;
    justify-content: center;
    margin-right: auto;
  }
  #fullscreen-btn { display: none; }   /* no fullscreen toggle on mobile */

  main { padding: 12px; }

  /* Both sidebars live in an off-canvas drawer, stacked (left then right) */
  .drawer {
    display: block;
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 86%;
    max-width: 340px;
    padding: 14px;
    background: var(--bg);
    border-right: 1px solid var(--line);
    z-index: 90;
    overflow-y: auto;
    transform: translateX(-102%);
    transition: transform 0.25s ease;
  }
  body.menu-open .drawer { transform: none; }

  .drawer-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 85;
    background: rgba(0, 0, 0, 0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
  }
  body.menu-open .drawer-backdrop { opacity: 1; pointer-events: auto; }

  /* Inside the drawer the bars are plain, full-width stacked blocks */
  .drawer header,
  .drawer .rightbar {
    position: static;
    width: 100%;
    height: auto;
    max-height: none;
    overflow: visible;
  }
  .drawer header { margin-bottom: 22px; }

  /* Theme icons (rainbow / dark / light) pinned to the foot of the drawer,
     below the version credits */
  .drawer > .theme-row {
    margin-top: 22px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
    gap: 10px;
  }

  /* Tap-to-type overlay: a real, transparent textarea sitting over the
     preview. The tap lands on it (so the keyboard opens); the rendered glyphs
     show through underneath. 16px font-size stops iOS from zooming on focus. */
  .preview-section { position: relative; }
  #preview-typer {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: transparent;
    caret-color: transparent;
    font-size: 16px;
    resize: none;
    outline: none;
    z-index: 5;
    -webkit-text-fill-color: transparent;
  }

  /* Specimen grid flows to the glyph size: ~4 narrow letters across, fewer
     when a row holds wide ones (.glyph-card.wide spans 2 tracks) — so rows
     land at 2/3/4 depending on width. The `main` prefix lifts specificity
     above the later base .glyph-grid rule (media queries don't add
     specificity, so source order would otherwise win). */
  main .glyph-grid {
    grid-template-columns: repeat(auto-fill, minmax(calc(var(--spec-size, 56px) + 28px), 1fr));
  }
  main .glyph-card { padding: 10px 6px 6px; }
  main .glyph-card svg { height: var(--spec-size, 118px); }
}

.control-group label {
  display: block;
  color: var(--muted);
  margin-bottom: 4px;   /* half the section-header gap (h2 margin-bottom 8px) */
}

.metric-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
  margin-bottom: 2px;
}
.metric-row span { color: var(--text); }
.metric-row input[type="number"] {
  width: 62px;
  padding: 3px 6px;
  border: 1px solid var(--line);
  background: transparent;   /* rides the page bg, so no fade desync flash */
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.metric-btn-row { display: flex; gap: 6px; margin-top: 6px; }
.metric-btn-row button { flex: 1 1 0; min-width: 0; padding: 5px 0; }
#metrics-btn { width: 100%; margin-top: 6px; margin-bottom: 14px; padding: 5px 0; }
#metrics-btn.on {
  color: var(--accent);
  border-color: var(--accent);
}
#metrics-btn.on:hover,
#metrics-btn.on:active { color: var(--bg); }

/* Right toolbar: seed and metrics, mirroring the left module */
.rightbar {
  width: 208px;
  flex-shrink: 0;
  position: sticky;
  top: 14px;
  height: calc(100vh - 28px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* Theme + fullscreen pinned to the bottom of the left column */
header .theme-row {
  margin-top: auto;
  flex-shrink: 0;
  justify-content: flex-start;
}
.seed-row { display: flex; gap: 6px; }
.seed-row input { flex: 1; min-width: 0; }
.seed-row button {
  width: 62px;            /* matches the metric inputs below */
  padding: 5px 0;
  flex-shrink: 0;
}

/* Load font: upload button with a clear (x) beside it */
.upload-row { display: flex; gap: 6px; }
.upload-row button:first-child { flex: 1; min-width: 0; padding: 5px 8px; }
#upload-clear {
  width: 28px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  font-size: 14px;
  line-height: 1;
}
.upload-name {
  margin-top: 4px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.upload-name.error { color: #ff6b6b; }

/* Outline select + line-gap input: two labeled half-width columns */
.outline-row { display: flex; gap: 4px; margin-top: 10px; }
.outline-col { flex: 1 1 50%; min-width: 0; }
.outline-col select { width: 100%; }
.outline-col input[type="number"] {
  width: 100%;
  padding: 5px 8px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.outline-col input[type="number"]:disabled { opacity: 0.35; }

/* Graphic outline-style picker */
#outline-styles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  margin-top: 14px;
  margin-bottom: 14px;
}
.outline-style-btn {
  padding: 3px 0 1px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}
.outline-style-btn:hover { color: var(--bg); }
.outline-style-btn.on {
  color: var(--accent);
  border-color: var(--accent);
}
.outline-style-btn.on:hover,
.outline-style-btn.on:active { color: var(--bg); }

input[type="text"], select {
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  color: var(--text);
}

#seed-input { width: 100px; font-variant-numeric: tabular-nums; }

/* Custom dropdowns: drop the native chrome, draw our own chevron in the
   ink colour (swapped by theme so it stays black/white). */
select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 26px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23ffffff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
[data-theme="light"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23000000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
}

/* No native focus ring on fields (dropdowns, inputs) or buttons. */
input:focus, select:focus, button:focus { outline: none; }

/* ---------- Custom dropdown (replaces the native select popup) ---------- */
.select-wrap { position: relative; }
.select-wrap select { display: none; }
.select-trigger {
  width: 100%;
  padding: 5px 26px 5px 8px;
  border: 1px solid var(--line);
  color: var(--text);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23ffffff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E") no-repeat right 9px center;
}
[data-theme="light"] .select-trigger {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23000000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
}
.select-trigger:focus { outline: none; }
.select-panel {
  position: fixed;
  z-index: 100;
  max-height: 280px;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--line);
}
.select-option {
  padding: 6px 8px;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.select-option.sel { background: color-mix(in srgb, var(--text) 12%, transparent); }
.select-option.active { background: var(--accent); color: #000000; }

button {
  padding: 5px 14px;   /* matches the Random button height */
  border: 1px solid var(--line);
  border-radius: 0;
  background: transparent;   /* shows the page bg; no lag when the seed repaints */
  color: var(--text);
  cursor: pointer;
  transition: background 0.15s ease;
}
button:hover,
button:active {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}

button.primary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--line);
  padding: 5px 14px;
}
/* Equal specificity to button.primary, so the base hover reaches it */
button.primary:hover,
button.primary:active {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}

.buttons { display: flex; flex-direction: column; gap: 8px; }

.download-status { font-size: 12px; color: var(--muted); line-height: 1.3; }

/* Tuning sliders */
.sliders {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 14px;      /* full line break after the Counters dropdown */
  margin-bottom: 14px;   /* full line break after the Tracking slider */
}

/* Name and slider share one row: [ Weight ][ ====o==== ] */
.slider-group {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
}
.slider-group > label {
  flex: 0 0 58px;
  margin-bottom: 0;
  line-height: 1;
}
.slider-group > .slider-wrap { flex: 1 1 auto; min-width: 0; }

/* Value pill rides on the slider thumb. The track line is drawn on the
   wrap (like every other UI line) rather than the native track, which
   rendered its 1px inconsistently between sliders. */
.slider-wrap {
  position: relative;
  height: 18px;
  background: linear-gradient(var(--line), var(--line)) no-repeat left center / 100% 1px;
}

.slider-wrap input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 18px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}

.slider-wrap input[type="range"]::-webkit-slider-runnable-track {
  height: 1px;
  background: transparent;
}

/* The native thumb stays invisible (hit area only); the pill span is the
   visible thumb, so it can glide to new positions on seed refresh. */
.slider-wrap input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 34px;
  height: 16px;
  border-radius: 8px;
  background: transparent;
  border: none;
  margin-top: -7px;
}

.slider-wrap input[type="range"]::-moz-range-track {
  height: 1px;
  background: transparent;
}

.slider-wrap input[type="range"]::-moz-range-thumb {
  width: 34px;
  height: 16px;
  border-radius: 8px;
  background: transparent;
  border: none;
}

.slider-pill {
  position: absolute;
  top: 1px;
  height: 16px;
  min-width: 34px;
  border-radius: 8px;
  background: var(--accent);
  left: calc(17px + (100% - 34px) * var(--pct, 50) / 100);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--bg);   /* value knocks out to the background colour */
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* Pills slide to their new spots when a seed lands */
.sliders.glide .slider-pill { transition: left 0.35s ease; }

/* ---------- Preview ---------- */
.preview-section { margin-bottom: 40px; }

/* Title line-height and margin mirror the sidebar's "Seed" label, so the
   title text aligns with "Seed" and the lattice top with the seed box. */
.preview-header { margin: 0 0 4px; }

/* Bare title line — no container around the Wikipedia title. */
#preview-input {
  width: 100%;
  border: none;
  background: transparent;
  padding: 0;
  line-height: normal;   /* identical line box to the sidebar labels */
  white-space: pre-wrap;
  caret-color: var(--accent);
}
#preview-input:focus { outline: none; border-bottom: 1px solid var(--line); }
#preview-input.title-label { color: var(--muted); }
#preview-input:empty::before { content: attr(data-placeholder); color: var(--muted); }

/* Title characters enter exactly like the glyphs below */
.tchar {
  display: inline-block;
  animation: glyph-in 0.22s ease-out backwards;
  animation-delay: calc(var(--i, 0) * 1ms);
}

.preview {
  background: transparent;
  border: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  row-gap: 0;
  min-height: 150px;
  overflow: visible;
}

/* Every preview letter sits in its own box; adjacent boxes share a line. */
.preview-glyph {
  border: 1px solid color-mix(in srgb, var(--text) 22%, transparent);
  margin-right: -1px;
  margin-bottom: -1px;
  display: flex;
  align-items: center;
}
.preview-glyph svg { height: var(--spec-size, 120px); width: auto; display: block; }

.preview-space {
  border: 1px solid color-mix(in srgb, var(--text) 22%, transparent);
  margin-right: -1px;
  margin-bottom: -1px;
  width: var(--space, 26px);
  flex-shrink: 0;
}

.preview-empty { color: var(--muted); align-self: center; }

/* Typing directly in the specimen */
#preview { cursor: text; outline: none; }

/* Zero-width in flow: the caret rides the boundary between two boxes */
.spec-caret {
  width: 0;
  position: relative;
  flex-shrink: 0;
  align-self: stretch;
  color: var(--accent);
  z-index: 2;
  pointer-events: none;
}
.spec-caret svg {
  position: absolute;
  top: 0;
  left: 0;
  transform: translateX(-50%);
  height: 100%;          /* always the full height of the glyph box */
  width: auto;
  overflow: visible;
}

/* Selected letters flood with the accent, type flips to black */
.preview-glyph.sel,
.preview-space.sel { background: var(--accent); }
.preview-glyph.sel svg [fill="#ffffff"] { fill: #000000; }
.preview-glyph.sel svg [stroke="#ffffff"] { stroke: #000000; }
.preview-glyph.sel svg [fill="#000000"] { fill: var(--accent); }
.preview-glyph.sel svg [stroke="#000000"] { stroke: var(--accent); }
@keyframes caret-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.1; }
}

/* ---------- Specimen ---------- */
.glyph-section { margin-bottom: 36px; }

.glyph-section h2 {
  color: var(--muted);
  margin-bottom: 8px;
}

.glyph-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 0;
}

.glyph-card {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--text) 22%, transparent);
  border-radius: 0;
  margin: 0 -1px -1px 0;   /* adjacent cards share a single line */
  padding: 14px 12px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  transition: background-color 0.15s ease;   /* colour only — never slide the metric-line gradient */
}
.glyph-card:hover,
.glyph-card:active {
  background: var(--accent);
  transform: none;   /* no movement or enlargement on hover */
}
/* Ink flips to black on the accent; background-coloured paints follow */
.glyph-card:hover svg [fill="#ffffff"],
.glyph-card:active svg [fill="#ffffff"] { fill: #000000; }
.glyph-card:hover svg [stroke="#ffffff"],
.glyph-card:active svg [stroke="#ffffff"] { stroke: #000000; }
.glyph-card:hover svg [fill="#000000"],
.glyph-card:active svg [fill="#000000"] { fill: var(--accent); }
.glyph-card:hover svg [stroke="#000000"],
.glyph-card:active svg [stroke="#000000"] { stroke: var(--accent); }
.glyph-card:hover .glyph-label,
.glyph-card:active .glyph-label { color: #000000; }

.glyph-card.wide { grid-column: span 2; }

.glyph-card svg { height: 118px; width: auto; max-width: 100%; display: block; }

.glyph-label { color: var(--muted); }

/* Quick staggered entrance when a new seed lands */
@keyframes glyph-in {
  from { opacity: 0; transform: translateY(8px) scale(0.9); }
  to   { opacity: 1; transform: none; }
}
.glyph-enter svg {
  animation: glyph-in 0.22s ease-out backwards;
  animation-delay: calc(var(--i, 0) * 1ms);
}
