:root {
  /* Flat dark — one surface; structure via hairlines, not nested gray cards */
  --bg: #181818;
  --paper: #181818;
  --ink: #f2f2f2;
  --muted: #a8a8a8;
  --line: #333333;
  --accent: #c45c5c; /* errors / destructive only */
  --chrome: #b8b8b8; /* inactive UI chrome — never competes with score colors */
  --good: #5fbf7a;
  --warn: #c9a34a;
  --bad: #c43c3c;
  --chip: #2a2a2a;
  /* Product: Manrope UI body; mono stack for input/brand + analysis (cycled via toolbar). */
  --font-sans: "Manrope", "Noto Sans", "Segoe UI", system-ui, sans-serif;
  --font-mono: "Iosevka Aile", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --font-ui: var(--font-sans);
  --score-col: 4.35rem;
  /* Trust frame: hairline around syl group + IPA */
  --trust-frame: 38%;
  --trust-outline: 1px;
  --trust-outline-offset: 2px;
  /* How far the colored frame sits outside the analysis content box */
  --trust-outset: calc(var(--trust-outline) + var(--trust-outline-offset));
  --content-inline: 0.85rem;
  --chrome-right: 0.35rem;
  --chrome-btn: 2rem;
  --chrome-gap: 0.05rem;
  /* Closed fallback; live width from JS (--chrome-cluster / --chrome-fade-ramp) */
  --chrome-cluster: 2.4rem;
  --chrome-fade-ramp: 1.75rem;
  --analysis-pair-gap: 0.72rem;
  /* Clear air between stacked trust outlines */
  --analysis-stack-gap: calc(var(--trust-outset) * 2 + 0.45rem);
  /* Horizontal air between trust outlines (outsets + a sliver of clear) */
  --analysis-word-gap: calc(var(--trust-outset) * 2 + 0.4rem);
  /* One vertical step between rhyme/result blocks */
  --rhyme-air: 0.28rem;
  /* Within a block: word→bars a bit tighter; bars→IPA closer still */
  /* Target visual air (overridden in px by font-ink.js per face). */
  --brace-air: 0.06rem;
  --brace-ipa-air: 0.06rem;
  /* Debug ±px nudges (0 = leave product defaults). */
  --brace-air-nudge: 0px;
  --brace-ipa-air-nudge: 0px;
  --rhyme-air-nudge: 0px;
  --brace-air-eff: calc(var(--brace-air) + var(--brace-air-nudge));
  --brace-ipa-air-eff: calc(var(--brace-ipa-air) + var(--brace-ipa-air-nudge));
  --rhyme-air-eff: calc(var(--rhyme-air) + var(--rhyme-air-nudge));
  --word-ink-pull: 0px;
  --ortho-ink-below: 0px;
  --ipa-ink-above: 0px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  /* Manrope = UI Latin; Noto Sans = IPA / rare glyphs */
  font: 16px/1.45 var(--font-ui);
  direction: ltr;
  color-scheme: dark;
  font-feature-settings: "kern" 1, "liga" 1;
}

/* Full-bleed strip above the app — blunt “outside” chrome */
.debug-dock {
  display: none;
  width: 100%;
  margin: 0;
  padding: 0;
  background: #0e0e0e;
  border-bottom: 3px solid #5a5a5a;
  color: #c8c8c8;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.78rem;
  line-height: 1.3;
  z-index: 40;
  overflow: visible;
}

html[data-debug="1"] .debug-dock,
html[data-debug="1"] .debug-dock[hidden] {
  display: block !important;
}

.debug-dock-bar {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.55rem;
  max-width: 920px;
  margin: 0 auto;
  padding: 0.45rem 1.2rem 0.7rem;
  position: relative;
}

.debug-dock-head {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  position: sticky;
  top: 0;
  z-index: 3;
  margin: 0 -0.25rem 0 0;
  padding: 0.1rem 0;
  background: #0e0e0e;
  pointer-events: none;
}

.debug-dock-tag {
  position: static;
  flex: 0 0 auto;
  font: inherit;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #8a8a8a;
  border: 1px solid #3a3a3a;
  background: #0e0e0e;
  padding: 0.18rem 0.4rem;
  cursor: pointer;
  pointer-events: auto;
  z-index: 4;
}

.debug-dock-tag:hover,
.debug-dock-tag:focus-visible {
  color: #ddd;
  border-color: #666;
  outline: none;
}

.debug-dock-tag:active {
  color: #fff;
}

.debug-font-controls {
  flex-wrap: nowrap;
}

.debug-font-cycle {
  display: inline-flex;
  border: 1px solid #444;
  flex: 0 0 auto;
}

.debug-font-step {
  min-width: 1.55rem;
  padding: 0.28rem 0.35rem;
  line-height: 1;
}

.debug-font-step + .debug-font-step {
  border-left: 1px solid #444;
}

.debug-font-controls .debug-select {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
}

.debug-row {
  display: grid;
  grid-template-columns: 6.75rem minmax(0, 1fr);
  align-items: center;
  column-gap: 0.85rem;
  row-gap: 0.35rem;
  min-height: 1.85rem;
}

.debug-row > .debug-field-label {
  grid-column: 1;
  justify-self: start;
}

.debug-row-controls {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.65rem;
  min-width: 0;
}

.debug-field {
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.4rem 0.55rem;
  margin: 0;
}

.debug-field-label {
  color: #7a7a7a;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.65rem;
  flex: 0 0 auto;
  line-height: 1.2;
}

.debug-select {
  font: inherit;
  font-size: 0.78rem;
  color: #e8e8e8;
  background: #1a1a1a;
  border: 1px solid #444;
  border-radius: 0;
  padding: 0.28rem 0.45rem;
  min-width: 12rem;
  max-width: min(22rem, 100%);
  flex: 1 1 auto;
}

.debug-select:focus-visible {
  outline: 1px solid #888;
  outline-offset: 1px;
}

.debug-flex-block.is-disabled {
  opacity: 0.38;
  pointer-events: none;
}

.debug-seg {
  display: inline-flex;
  border: 1px solid #444;
  flex: 0 0 auto;
}

.debug-seg-btn {
  font: inherit;
  font-size: 0.72rem;
  color: #9a9a9a;
  background: #161616;
  border: 0;
  padding: 0.28rem 0.55rem;
  cursor: pointer;
  white-space: nowrap;
}

.debug-seg-btn + .debug-seg-btn {
  border-left: 1px solid #444;
}

.debug-seg-btn:hover {
  color: #ddd;
}

.debug-seg-btn.is-on {
  color: #111;
  background: #b8b8b8;
}

.debug-tog-btn {
  border: 1px solid #444;
}

.debug-slider {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
  flex: 0 0 auto;
}

.debug-slider input[type="range"] {
  width: 7rem;
  accent-color: #9a9a9a;
}

.debug-slider output {
  font-variant-numeric: tabular-nums;
  min-width: 1.6rem;
  text-align: right;
  color: #e8e8e8;
}

.debug-px-unit {
  color: #7a7a7a;
}

.debug-row-toggles {
  gap: 0.75rem 1.4rem;
}

.debug-slider[hidden] {
  display: none !important;
}

.debug-scale-prefix {
  color: #7a7a7a;
}

.page {
  max-width: 920px;
  min-height: 100dvh;
  margin: 0 auto;
  /* Tight top once results are up — idle centering uses .workspace pad */
  padding: 0.65rem 1.2rem 1.4rem;
  display: flex;
  flex-direction: column;
}

.page.is-hero {
  padding-top: 1.2rem;
}

.lang-switch {
  display: inline-flex;
  gap: 0.15rem;
  border: 1px solid var(--line);
  background: var(--paper);
  padding: 0.1rem;
}

.lang-btn {
  font: inherit;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--muted);
  background: transparent;
  border: 0;
  padding: 0.15rem 0.45rem;
  cursor: pointer;
}

.lang-btn:hover {
  color: var(--ink);
}

.lang-btn.is-active {
  color: var(--bg);
  background: var(--ink);
}

.home-link {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  border-bottom: 1px dotted transparent;
  white-space: nowrap;
}

.home-link:hover {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

.ver {
  flex-shrink: 0;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  letter-spacing: 0.04em;
}

.site-foot {
  margin-top: auto;
  padding-top: 1.1rem;
  padding-bottom: max(0.55rem, env(safe-area-inset-bottom, 0px));
  border-top: 0;
  font-size: 0.55rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  color: color-mix(in srgb, var(--muted) 26%, transparent);
  min-height: 0;
  flex-shrink: 0;
}

/* Idle: a bit more air above the whisper link */
.page.is-hero .site-foot {
  padding-top: 2.2rem;
}

.legal-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 0;
}

.legal-link:hover,
.legal-link:focus-visible {
  color: color-mix(in srgb, var(--muted) 58%, transparent);
}

.composer-row {
  display: flex;
  align-items: stretch;
  gap: 0;
  width: 100%;
}

.workspace {
  width: 100%;
  border: 0;
  border-radius: 0;
  background: transparent;
  overflow: hidden;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  min-height: 0;
  /* Idle: float input toward mid-viewport (thumb / mouse reach) */
  padding-top: 0.15rem;
  transition: padding-top 0.48s cubic-bezier(0.22, 1, 0.36, 1);
}

.page.is-hero .workspace {
  /* Optical mid of the viewport (thumb / mouse reach), animates down when results land */
  padding-top: max(3.5rem, calc(50dvh - 4.75rem));
}

/* Input + optional toolbar + input-analysis */
.query-shell {
  position: relative;
}

.composer {
  position: relative;
  z-index: 0;
  isolation: isolate;
  flex: 1 1 auto;
  min-width: 0;
  /* pad-top + 1.1rem/1.2 line — no bottom pad (marks supply --brace-air) */
  --composer-pad-top: 0.55rem;
  height: calc(var(--composer-pad-top) + 1.1rem * 1.2);
  min-height: calc(var(--composer-pad-top) + 1.1rem * 1.2);
  border: 0;
  border-radius: 0;
  background: transparent;
  overflow: hidden;
  transition: height 0.18s ease, border-color 0.15s ease;
}

.composer.is-loading {
  height: calc(var(--composer-pad-top) + 1.1rem * 1.2);
  border-color: transparent;
}

.composer.is-error {
  height: calc(var(--composer-pad-top) + 1.1rem * 1.2);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.composer.is-ready {
  height: calc(var(--composer-pad-top) + 1.1rem * 1.2);
  border-color: transparent;
  background: transparent;
}

.input-host {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-height: 100%;
  overflow: hidden;
  opacity: 1;
}

.input-host[hidden] {
  display: none;
}

.input-host.is-entering {
  animation: input-enter 0.42s ease both;
}

@keyframes input-enter {
  from { opacity: 0; }
  to { opacity: 1; }
}

.qframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: transparent;
  color-scheme: dark;
  position: relative;
  z-index: 0;
  outline: none;
}

.qframe:focus,
.qframe:focus-visible {
  outline: none;
}

/*
  Fade ramp ends at the invisible chrome divider (left edge of icons).
  Solid scrim covers the icon cluster so text never shows through.
  Height is locked to the input host only — never stretch into analysis.
*/
.input-fade {
  position: absolute;
  z-index: 2;
  top: 0;
  bottom: auto;
  height: 2.75rem;
  max-height: 100%;
  right: var(--chrome-cluster);
  width: var(--chrome-fade-ramp);
  pointer-events: none;
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--paper) 40%, transparent) 40%,
    var(--paper) 92%
  );
  opacity: 1;
  transition:
    right 0.34s cubic-bezier(0.22, 1, 0.36, 1),
    width 0.34s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.18s ease;
}

/* While editing, show the caret end — hide the idle fade */
.input-host.is-focused .input-fade {
  opacity: 0;
}

.input-chrome {
  position: absolute;
  z-index: 3;
  top: 0;
  bottom: auto;
  height: 2.75rem;
  max-height: 100%;
  right: var(--chrome-right);
  left: auto;
  width: max-content;
  max-width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  gap: var(--chrome-gap);
  pointer-events: none;
}

/* Opaque plate under icons (= invisible divider from the text lane) */
.input-chrome::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  bottom: auto;
  height: 100%;
  left: 0;
  right: calc(-1 * var(--chrome-right));
  background: var(--paper);
  pointer-events: none;
}

.input-chrome > * {
  pointer-events: auto;
}

.input-settings {
  position: relative;
  flex: 0 0 auto;
  width: var(--chrome-btn);
  height: var(--chrome-btn);
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 2px;
  background: transparent;
  color: color-mix(in srgb, var(--muted) 70%, transparent);
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}

.input-settings:hover,
.input-settings:focus-visible {
  color: color-mix(in srgb, var(--muted) 88%, var(--ink));
  outline: none;
}

.input-settings:active {
  color: var(--ink);
}

.input-settings[aria-expanded="true"] {
  color: var(--ink);
}

.input-settings-icon,
.tool-icon {
  width: 1rem;
  height: 1rem;
  display: block;
  overflow: visible;
}

/* Multi-reading hint while analysis is off: muted ↔ ink */
@keyframes chrome-attention {
  0%,
  100% {
    color: color-mix(in srgb, var(--muted) 62%, transparent);
  }
  50% {
    color: var(--ink);
  }
}

.input-settings.is-attention,
.tool-btn.is-attention {
  animation: chrome-attention 1.55s ease-in-out infinite;
}

.input-settings.is-attention:hover,
.input-settings.is-attention:focus-visible,
.tool-btn.is-attention:hover,
.tool-btn.is-attention:focus-visible {
  animation: none;
  color: var(--ink);
}

/*
  Tools expand left from the settings cluster (no second row / no divider).
  Closed: width 0. Open: slide out beside the gear.
*/
/*
  Tools expand left from the settings cluster (no second row / no divider).
  Width must stay auto — a fixed tray width poisons abspos shrink-to-fit
  and made the input inset far too large.
*/
.toolbar {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  gap: 0.22rem;
  flex: 0 0 auto;
  width: auto;
  max-width: 0;
  min-width: 0;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateX(0.45rem);
  pointer-events: none;
  transition:
    max-width 0.34s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.22s ease,
    transform 0.34s cubic-bezier(0.22, 1, 0.36, 1);
}

.toolbar.is-open {
  max-width: 14.5rem;
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
  /* keep overflow hidden — voice panel lives outside composer */
}

.tool-btn {
  flex: 0 0 auto;
  width: 1.85rem;
  height: 1.85rem;
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 2px;
  background: transparent;
  color: color-mix(in srgb, var(--muted) 62%, transparent);
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease, opacity 0.15s ease;
}

.tool-btn:hover,
.tool-btn:focus-visible {
  color: color-mix(in srgb, var(--muted) 88%, var(--ink));
  outline: none;
}

.tool-btn.is-on {
  color: var(--ink);
}

.tool-btn.is-on:hover,
.tool-btn.is-on:focus-visible {
  color: var(--ink);
}

.tool-btn:disabled {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

.prefs-toggle {
  flex: 0 0 auto;
  width: 3.35rem;
  align-self: stretch;
  min-height: 3.35rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  color: var(--muted);
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.composer-row.is-loading .prefs-toggle,
.composer-row.is-error .prefs-toggle {
  border-color: var(--line);
}

.prefs-toggle:hover {
  color: var(--ink);
  border-color: var(--chrome);
}

.prefs-toggle[aria-expanded="true"] {
  color: var(--bg);
  background: var(--ink);
  border-color: var(--ink);
}

.prefs-toggle-icon {
  display: block;
}

.status {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

/* Progress lives inside the composer shell (same box as the future input). */
.lex-load {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.35rem;
  margin: 0;
  padding: 0 var(--content-inline);
  border: 0;
  background: transparent;
  pointer-events: none;
  opacity: 1;
  transition: opacity 0.38s ease;
}

.lex-load.is-exiting {
  opacity: 0;
}

.lex-load[hidden] {
  display: none;
}

.composer.is-ready .lex-load:not(.is-exiting) {
  display: none;
}

.lex-load-label {
  margin: 0;
  font-size: 0.82rem;
  letter-spacing: 0.01em;
  color: var(--muted);
  text-align: center;
}

.lex-load-label[hidden] {
  display: none;
}

.lex-load-track {
  position: relative;
  /* Integer px — rem heights blur to uneven thickness on DPR screens */
  height: 4px;
  border: 0;
  background: var(--chip);
  overflow: hidden;
  flex-shrink: 0;
  border-radius: 0;
}

.lex-load-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 4px;
  width: 100%;
  background: color-mix(in srgb, var(--ink) 55%, var(--muted));
  transform-origin: left center;
  transform: scaleX(0);
  /* scaleX from rAF — avoids subpixel width rounding vs track */
  will-change: transform;
}

.lex-load-track.is-indeterminate .lex-load-fill {
  /* Sweep via left (not translate) so height stays crisp */
  width: 28%;
  transform: none;
  animation: lex-indeterminate 1.15s ease-in-out infinite;
}

.lex-load.is-error .lex-load-track {
  display: none;
}

.lex-load.is-error .lex-load-label {
  display: block;
  color: var(--accent);
}

@keyframes lex-indeterminate {
  0% { left: -30%; }
  100% { left: 105%; }
}

.panels[hidden],
.results[hidden] {
  display: none;
}

.prefs-drawer {
  margin: 0.75rem 0 0.15rem;
}

.prefs-drawer[hidden] {
  display: none;
}

.prefs {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0;
}

.prefs-panel {
  border: 1px solid var(--line);
  background: var(--paper);
}

.prefs-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.4rem 0.65rem;
  border-bottom: 1px solid var(--line);
}

.prefs-panel-title {
  font-size: 0.82rem;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.pref {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.82rem;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  min-width: 0;
}

.pref.check {
  display: grid;
  grid-template-columns: 1.1rem 1fr;
  align-items: start;
  gap: 0.45rem;
  margin: 0;
  line-height: 1.35;
}

.pref.check input[type="checkbox"] {
  margin: 0.15rem 0 0;
  accent-color: var(--ink);
}

.prefs-sliders > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  font-size: 0.82rem;
  color: var(--muted);
  padding: 0.4rem 0.65rem;
  letter-spacing: 0.02em;
}

.prefs-sliders > summary::-webkit-details-marker {
  display: none;
}

.prefs-sliders > summary::before {
  content: "▸";
  display: inline-block;
  width: 1em;
  color: var(--muted);
}

.prefs-sliders[open] > summary::before {
  content: "▾";
}

.prefs-sliders > summary:hover {
  color: var(--ink);
}

.prefs-matrix {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.55rem 1.4rem;
  padding: 0.65rem;
}

.prefs-sliders .prefs-matrix {
  padding: 0.65rem;
  border-top: 1px solid var(--line);
}

@media (max-width: 620px) {
  .prefs-matrix {
    grid-template-columns: 1fr;
  }
}

.pref.range {
  display: grid;
  grid-template-columns: minmax(7.5rem, 9.5rem) 1fr 2.4rem;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
}

.pref.range input[type="range"] {
  width: 100%;
  min-width: 0;
  accent-color: var(--ink);
}

.pref-reset {
  border-bottom: 1px dotted transparent;
}

.pref-reset:hover {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

.pref-val {
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--ink);
  font-size: 0.8rem;
}

.prefs-reset-all {
  font: inherit;
  font-size: 0.78rem;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line);
  padding: 0.15rem 0.5rem;
  cursor: pointer;
  border-radius: 2px;
  flex-shrink: 0;
}

.prefs-reset-all:hover {
  color: var(--ink);
  border-color: var(--chrome);
}

.results {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: 0;
  border-top: 0;
}

/* Soft section cut: input analysis → rhyme results (full content width) */
.results::before {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0;
  left: var(--content-inline);
  right: var(--content-inline);
  height: 1px;
  background: color-mix(in srgb, var(--line) 55%, transparent);
  pointer-events: none;
}

.panel-rhymes {
  position: relative;
  z-index: 1;
  min-height: 0;
  border-top: 0;
  /* Same air below the rule as panel-units leaves above it */
  padding: var(--rhyme-air-eff) 0 0;
}

.panel {
  background: transparent;
  border: 0;
  /* No horizontal pad — borders stay full-bleed; content pads itself */
  padding: 0;
  min-height: 0;
}

/*
  Input analysis underlay: marks + IPA hang under the typed word.
  --input-under-slack cancels iOS textarea slack below the last line.
*/
.panel-units {
  position: relative;
  z-index: 1;
  min-height: 0;
  /* Slack = iOS textarea pad; word-ink-pull = empty line-box below glyph ink. */
  margin-top: calc(
    -1 * (var(--input-under-slack, 0px) + var(--word-ink-pull, 0px))
  );
  padding-top: 0;
  padding-bottom: var(--rhyme-air-eff);
  padding-left: var(--content-inline);
  padding-right: var(--chrome-cluster, 2.85rem);
}

.panel-units[hidden] {
  display: none;
}

.panel-rhymes .rhymes {
  padding-top: 0;
}

.panel h2 {
  margin: 0 0 0.7rem;
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}

.meta { letter-spacing: 0; text-transform: none; font-weight: 400; }

/*
  Analysis stack: continuous ortho, horizontal syllable marks (inset under letters),
  IPA under a shared baseline. No side boxes, no /slashes/.
*/
.analysis-stack {
  /* Same stroke weight for all; stress = opacity only */
  --brace-stroke: 1.6px;
  --brace-slot: 1.6px;
  --brace-inset: 0.07em;
  /* --brace-air / --brace-ipa-air come from :root */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  direction: ltr;
  unicode-bidi: isolate;
  min-width: 0;
}

.syl-track {
  display: inline-flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  align-content: flex-start;
  gap: 0;
  max-width: 100%;
}

/* Word = flex group of syllable cells; wrap between syllables only
   (input underlay + results share this — never mid-letter). */
.syl-word {
  display: inline-flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  max-width: 100%;
}

.syl-cell {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex: 0 0 auto;
  width: fit-content;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

/* Flex mode: fixed syllable fields; glyphs fill via axes + scaleX. */
html[data-font-mode="flex"] .analysis-stack,
html[data-font-mode="flex"] .syl-track,
html[data-font-mode="flex"] .syl-word {
  justify-content: flex-start;
  align-items: flex-start;
}

/*
  Ortho must read as one flowing word (no artificial letter gaps).
  Join air lives only on the braces — see --flex-brace-gap below.
*/
html[data-font-mode="flex"] .syl-word {
  --flex-brace-gap: 0.22em;
  column-gap: 0;
  row-gap: 0;
  align-items: flex-start;
}

html[data-font-mode="flex"] .syl-cell[data-syl-col] {
  flex: 0 0 auto;
  align-items: stretch;
  overflow: visible;
}

html[data-font-mode="flex"] .syl-ortho {
  display: block;
  box-sizing: border-box;
  text-align: left;
  letter-spacing: 0 !important;
  line-height: 1.2;
  height: 1.2em;
  overflow: visible;
  white-space: pre;
}

/* Brace-only joins (override product --brace-inset when cells abut). */
html[data-font-mode="flex"] .syl-cell .syl-brace {
  margin-left: 0;
}
html[data-font-mode="flex"] .syl-cell:not(.is-syl-last) .syl-brace {
  width: calc(100% - var(--flex-brace-gap, 0.22em));
  margin-left: 0;
}
html[data-font-mode="flex"] .syl-cell.is-syl-last .syl-brace {
  width: 100%;
  margin-left: 0;
}
html[data-font-mode="flex"] .syl-cell:not(.is-syl-first) .syl-brace {
  margin-left: 0;
  width: 100%;
}
html[data-font-mode="flex"] .syl-cell:not(.is-syl-first):not(.is-syl-last) .syl-brace {
  margin-left: 0;
  width: calc(100% - var(--flex-brace-gap, 0.22em));
}

html[data-font-mode="flex"] .syl-ipa {
  display: block;
  text-align: center;
  letter-spacing: normal;
  line-height: 1.25;
  min-height: 1.25em;
}

/*
  Flex + analysed input: show underlay ortho (flexed) on the textarea line;
  textarea text is transparent (caret stays). Clicks pass through panel-units.
*/
html[data-font-mode="flex"][data-flex-input="1"] .panel-units {
  pointer-events: none;
  margin-top: calc(
    -1 * (1.1rem * 1.2 + var(--input-under-slack, 0px) + var(--word-ink-pull, 0px))
  );
}

html[data-font-mode="flex"][data-flex-input="1"] .analysis-stack.is-underlay .syl-ortho {
  display: block;
  visibility: visible;
  height: auto;
  line-height: 1.2;
  overflow: visible;
  color: var(--ink);
  font-size: 1.1rem;
  font-weight: 400;
}

html[data-font-mode="flex"][data-flex-input="1"] .analysis-stack.is-underlay .syl-brace {
  margin-top: calc(var(--brace-air-eff) - var(--ortho-ink-below, 0px));
}

/* Mid marks only: ortho → brace → IPA */
.syl-ortho { order: 2; }
.syl-brace { order: 3; }
.syl-ipa { order: 4; }

.syl-gap {
  flex: 0 0 0.35em;
  width: 0.35em;
  align-self: stretch;
}

.syl-ortho {
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.15;
  color: var(--muted);
  /* pre: never wrap mid-syllable */
  white-space: pre;
  letter-spacing: 0;
}

/* Result row: ortho IS the name — braces hang directly under it */
.analysis-stack.is-primary .syl-ortho {
  font-size: 1.1rem;
  line-height: 1.2;
  color: var(--ink);
  font-weight: 400;
}

/*
  Underlay: ortho only sizes brace width (matches input glyphs).
  Zero vertical contribution — braces hang under the field with the
  same --brace-air as primary rhyme rows.
*/
.analysis-stack.is-underlay .syl-ortho {
  display: block;
  visibility: hidden;
  font-size: 1.1rem;
  line-height: 0;
  white-space: pre;
  height: 0;
  overflow: hidden;
  margin: 0;
  padding: 0;
  pointer-events: none;
  /* Match textarea metrics so underlay wrap == field wrap */
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "calt" 0;
}

/* Same word→mark air as primary; underlay panel already ink-pulled. */
.analysis-stack.is-underlay .syl-brace {
  margin-top: var(--brace-air-eff);
  margin-bottom: calc(var(--brace-ipa-air-eff) - var(--ipa-ink-above, 0px));
}

/*
  Horizontal syllable marks: full width on outer edges and mono syllables.
  Only shorten toward inter-syllable joins (gap = --brace-inset each side).
*/
.syl-brace {
  --brace-color: color-mix(in srgb, var(--chrome) 55%, transparent);
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: var(--brace-slot);
  /* Subtract line-box slack so air is ink→mark / mark→ink, not box→box. */
  margin-top: calc(var(--brace-air-eff) - var(--ortho-ink-below, 0px));
  margin-bottom: calc(var(--brace-ipa-air-eff) - var(--ipa-ink-above, 0px));
  margin-left: 0;
  padding: 0;
  border: none;
  border-radius: 1px;
  background: linear-gradient(var(--brace-color), var(--brace-color))
    center / 100% var(--brace-stroke) no-repeat;
  opacity: 0.42;
  pointer-events: none;
}

/* Join: shorten the right edge of every non-final syllable */
.syl-cell:not(.is-syl-last) .syl-brace {
  width: calc(100% - var(--brace-inset));
}

/* Join: shorten the left edge of every non-first syllable */
.syl-cell:not(.is-syl-first) .syl-brace {
  margin-left: var(--brace-inset);
  width: calc(100% - var(--brace-inset));
}

/* Middle: shortened on both sides of the joins */
.syl-cell:not(.is-syl-first):not(.is-syl-last) .syl-brace {
  margin-left: var(--brace-inset);
  width: calc(100% - 2 * var(--brace-inset));
}

.syl-cell.is-stress .syl-brace {
  opacity: 1;
}

.analysis-stack.q-syl-good .syl-brace {
  --brace-color: color-mix(in srgb, var(--good) 88%, transparent);
}
.analysis-stack.q-syl-warn .syl-brace {
  --brace-color: color-mix(in srgb, var(--warn) 88%, transparent);
}
.analysis-stack.q-syl-bad .syl-brace {
  --brace-color: color-mix(in srgb, var(--bad) 88%, transparent);
}

.syl-ipa {
  /* Don't expand the cell: hang under the ortho width */
  width: 0;
  min-width: 100%;
  box-sizing: border-box;
  font-family: var(--font-ui);
  font-feature-settings: "kern" 1;
  font-size: 0.58rem;
  /* Stable box so IPA glyphs share one baseline */
  line-height: 1.35;
  color: var(--muted);
  direction: ltr;
  unicode-bidi: isolate;
  margin-top: 0;
  /* Always centered under the brace / syllable */
  display: flex;
  justify-content: center;
  text-align: center;
  white-space: pre;
  overflow: visible;
}

/*
  Center under the brace without changing cell width.
  Keep width:0;min-width:100% (max-content was expanding syllables when
  IPA was longer than ortho — visible especially on iOS).
  flex + justify-content works on WebKit where text-align alone failed.
*/

.ipa-fallback {
  font-family: var(--font-ui);
  font-feature-settings: "kern" 1;
  font-size: 0.62rem;
  line-height: 1.2;
  color: var(--muted);
  direction: ltr;
  unicode-bidi: isolate;
  word-break: break-word;
  margin-top: 0;
  text-align: left;
  max-width: 100%;
}

.analysis-stack.q-ipa-good .syl-ipa,
.analysis-stack.q-ipa-good .ipa-fallback {
  color: color-mix(in srgb, var(--muted) 70%, var(--good));
}
.analysis-stack.q-ipa-warn .syl-ipa,
.analysis-stack.q-ipa-warn .ipa-fallback {
  color: color-mix(in srgb, var(--muted) 70%, var(--warn));
}
.analysis-stack.q-ipa-bad .syl-ipa,
.analysis-stack.q-ipa-bad .ipa-fallback {
  color: color-mix(in srgb, var(--muted) 70%, var(--bad));
}

/*
  UI body = Manrope (--font-ui). Input brand + analysis stacks = Iosevka Aile.
  Impressum stays Manrope.
*/
html {
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "calt" 0;
}

.analysis-stack,
.analysis-stack .syl-ortho,
.analysis-stack .syl-ipa,
.ipa-fallback,
.score-pct {
  font-family: var(--font-mono);
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "calt" 0;
}

.site-foot,
.site-foot .legal-link {
  font-family: var(--font-sans);
  font-variant-ligatures: normal;
  font-feature-settings: "kern" 1, "liga" 1;
}

.ipa-tok.is-diff {
  background: color-mix(in srgb, var(--muted) 28%, transparent);
  border-radius: 0.15em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.sentence-bits {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.65rem;
  direction: ltr;
  unicode-bidi: isolate;
}

.units {
  display: flex;
  flex-direction: column;
  gap: calc(var(--rhyme-air-eff) + 0.35rem);
}

.name-line {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  min-width: 0;
  max-width: 100%;
}

.name-line .name {
  min-width: 0;
}

/* Reading picker: opacity only — no fill/border fighting trust outlines */
.unit-choice {
  appearance: none;
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.unit-choice.is-solo {
  cursor: default;
}

/* Multi-reading: word once, stacked mark rows, IPA once */
.units-readings {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  max-width: 100%;
}

.units-readings .reading-marks {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  max-width: 100%;
}

.units-readings .reading-marks .unit-choice {
  width: auto;
  max-width: 100%;
  padding: 0;
  margin: 0;
  box-sizing: content-box;
}

.units-readings .reading-marks .unit-choice + .unit-choice {
  margin-top: 0.38rem;
}

.units-readings .reading-marks .analysis-stack.is-underlay .syl-brace {
  margin-top: var(--brace-air-eff);
  margin-bottom: 0;
}

.units-readings .unit-choice:not(.is-active) {
  opacity: 0.38;
}

.units-readings .unit-choice:not(.is-active):hover,
.units-readings .unit-choice:not(.is-active):focus-visible {
  opacity: 0.72;
  outline: none;
}

.units-readings .unit-choice.is-active {
  opacity: 1;
}

.units-readings .reading-ipa {
  margin-top: var(--rhyme-air-eff);
  padding-top: 0;
  pointer-events: none;
  max-width: 100%;
}

.units-readings .reading-ipa .analysis-stack.is-ipa-only.is-underlay .syl-ipa {
  margin-top: 0;
}

.unit-choice:not(.is-solo):not(.is-active) {
  opacity: 0.55;
}

.unit-choice:not(.is-solo):not(.is-active):hover,
.unit-choice:not(.is-solo):not(.is-active):focus-visible {
  opacity: 0.88;
  outline: none;
}

.unit-choice.is-active {
  opacity: 1;
  background: transparent;
}

.rhyme {
  /*
    Between blocks: --rhyme-air (consistent).
    Within a block: equal --brace-air above and below the syllable marks.
    Score sits in a fixed right column (under chrome) so % stays assigned.
    Vertically center % against the whole analysis stack (wrap-aware).
  */
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--score-col);
  column-gap: 0.65rem;
  align-items: center;
  padding-top: calc(var(--rhyme-air-eff) + 0.14rem);
  padding-bottom: calc(var(--rhyme-air-eff) + 0.14rem);
  padding-left: var(--content-inline);
  padding-right: var(--content-inline);
  border-bottom: 0;
}

.rhyme-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.rhyme-meta {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.35rem;
  flex: 0 0 auto;
  width: 100%;
  padding-top: 0;
}

.score-bar {
  --p: 0;
  --score-fill: var(--bad);
  width: 2.35rem;
  height: 0.3rem;
  border-radius: 1px;
  display: inline-block;
  flex: 0 0 auto;
  vertical-align: middle;
  background: linear-gradient(
    to right,
    var(--score-fill) calc(var(--p) * 1%),
    color-mix(in srgb, var(--line) 60%, transparent) 0
  );
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--line) 70%, transparent);
}

.score-pct {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  line-height: 1;
  flex: 0 0 auto;
  white-space: nowrap;
  color: var(--score-fill, var(--muted));
}

.rhyme-combo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05rem;
  height: 1.05rem;
  color: var(--muted);
  flex: 0 0 auto;
}

.rhyme-combo svg {
  width: 100%;
  height: 100%;
  display: block;
}

.rhyme .name {
  font-size: 1.1rem;
  /* Tight line box → padding-top measures to letter tops, not half-leading */
  line-height: 1;
}

.rhyme .sub {
  direction: ltr;
  unicode-bidi: isolate;
  margin-top: 0;
}

.empty { color: var(--muted); }

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
