:root {
    --bg: #1a1f2e;
    --card-front: #4d7eb8;
    --card-back: #2d8659;
    --text: #f5f5f5;
    --muted: rgba(255,255,255,0.7);
    --accent: #ffd166;
    --btn-bg: rgba(255,255,255,0.12);
    --btn-bg-hover: rgba(255,255,255,0.22);
  }
  * { box-sizing: border-box; }
  html, body {
    margin: 0; padding: 0;
    background: linear-gradient(135deg, #1a1f2e 0%, #2c3e50 100%);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 24px 16px;
  }
  /* Web only, non-phone: never collapse below settings-page width (560px content + 32px padding).
     Phones (≤480px) drop the min-width so the page fills the viewport instead of horizontally scrolling. */
  @media (min-width: 481px) {
    html:not(.native) body { min-width: 592px; }
  }
  header {
    text-align: center;
    margin-bottom: 20px;
    position: relative;
    width: 100%;
    max-width: 560px;
  }
  h1 {
    font-size: 22px;
    font-weight: 600;
    margin: 40px 0 4px;
  }
  .subtitle {
    color: var(--muted);
    font-size: 15px;
    margin-bottom: 40px;
  }
  .progress {
    margin: 16px 0 8px;
    color: var(--muted);
    font-size: 16px;
    font-variant-numeric: tabular-nums;
  }
  .progress-bar {
    width: 100%;
    max-width: 560px;
    height: 8px;
    background: rgba(255,255,255,0.1);
    border-radius: 4px;
    overflow: hidden;
    margin-bottom: 20px;
    cursor: pointer;
    touch-action: none;  /* let JS scrubber consume the gesture instead of scrolling */
  }
  .progress-bar:hover { background: rgba(255,255,255,0.16); }
  .progress-bar-fill {
    height: 100%;
    background: var(--accent);
    transition: width 0.25s ease;
    pointer-events: none;  /* clicks land on the parent for the scrubber */
  }
  .card-container {
    width: 100%;
    max-width: 560px;
    height: 313px;
    perspective: 1200px;
    margin-bottom: 24px;
  }
  .card {
    width: 100%;
    height: 100%;
    position: relative;
    transform-style: preserve-3d;
    transition: transform 0.55s cubic-bezier(0.4, 0.0, 0.2, 1);
    cursor: pointer;
    /* Kill the iOS/Safari blue tap-highlight flash on mobile when the card is tapped. */
    -webkit-tap-highlight-color: transparent;
  }
  /* On the Capacitor native shell, also disable selection and the long-press callout —
     the card is a tap/swipe target, not text to be selected. Web keeps normal text-selection
     so users can copy a phrase or translation to look it up. */
  .native .card {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
  }
  .card.flipped {
    transform: rotateX(180deg);
  }
  .card-face {
    position: absolute;
    inset: 0;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    border-radius: 18px;
    padding: 32px 28px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    box-shadow: 0 18px 40px rgba(0,0,0,0.35);
    text-align: center;
  }
  .card-front { background: var(--card-front); }
  .card-back  { background: var(--card-back); transform: rotateX(180deg); }
  .category {
    /* Absolutely positioned + centered along the top of the card so the speaker
       and menu buttons in the corners (and the phrase below) stay perfectly
       independent of label length. */
    position: absolute;
    top: 18px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 13px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255,255,255,0.7);
    font-weight: 600;
    max-width: calc(100% - 120px);  /* don't bleed under the corner buttons */
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    pointer-events: none;            /* a long category label should never block taps */
  }
  /* Shared base for the round corner buttons (speaker / card menu).
     Sized at 48×48 (70% of the earlier 68×68 thumb-friendly size). */
  .speaker-btn,
  .card-menu-btn {
    position: absolute;
    top: 10px;
    background: rgba(255,255,255,0.15);
    border: none;
    color: var(--text);
    width: 48px;
    height: 48px;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.15s ease, transform 0.1s ease;
  }
  .speaker-btn { right: 14px; }
  .card-menu-btn { left: 14px; }
  .speaker-btn:hover,
  .card-menu-btn:hover { background: rgba(255,255,255,0.28); }
  .speaker-btn:active,
  .card-menu-btn:active { transform: scale(0.92); }
  .speaker-btn.playing { background: var(--accent); color: #1a1f2e; }
  .speaker-btn svg,
  .card-menu-btn svg { width: 26px; height: 26px; }
  /* The speaker button shows one of three icons depending on playback mode + submode:
       - default (manual / auto-speak): speaker (volume_up)
       - hands-free, playing:           pause bars (button pauses the loop)
       - hands-free, paused:            play triangle (button resumes the loop)
     applyHandsFreeUIState() in app.js toggles the body classes that gate these rules. */
  .speaker-btn .speaker-icon-pause,
  .speaker-btn .speaker-icon-play { display: none; }
  body.playback-mode-handsfree .speaker-btn .speaker-icon-default { display: none; }
  body.playback-mode-handsfree .speaker-btn .speaker-icon-pause { display: block; }
  body.playback-mode-handsfree.handsfree-paused .speaker-btn .speaker-icon-pause { display: none; }
  body.playback-mode-handsfree.handsfree-paused .speaker-btn .speaker-icon-play { display: block; }
  .phrase {
    font-size: clamp(28px, 5vw, 42px);
    font-weight: 600;
    line-height: 1.25;
    margin: 0;
  }
  .example {
    margin-top: 28px;
    max-width: 92%;
    text-align: center;
  }
  .example-sv {
    font-size: clamp(15px, 2.4vw, 18px);
    font-weight: 500;
    color: rgba(255,255,255,0.95);
    line-height: 1.35;
  }
  .example-en {
    margin-top: 4px;
    font-size: 15px;
    color: rgba(255,255,255,0.7);
    font-style: italic;
    line-height: 1.4;
  }
  .example:empty { display: none; }
  .literal {
    margin-top: 12px;
    font-size: 15px;
    color: rgba(255,255,255,0.75);
    line-height: 1.6;
    max-width: 92%;
    text-align: center;
  }
  .literal .lit-sv {
    font-weight: 600;
    color: rgba(255,255,255,0.95);
  }
  .literal .lit-en {
    color: rgba(255,255,255,0.65);
    font-style: italic;
  }
  .literal .lit-sep {
    color: rgba(255,255,255,0.4);
    margin: 0 6px;
  }
  .notes {
    margin-top: 12px;
    font-size: 14px;
    color: rgba(255,255,255,0.6);
    font-style: italic;
    max-width: 90%;
  }
  .flip-hint {
    position: absolute;
    bottom: 14px;
    left: 0; right: 0;
    text-align: center;
    font-size: 13px;
    color: rgba(255,255,255,0.5);
    letter-spacing: 0.5px;
  }
  .controls {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: center;
    max-width: 560px;
    width: 100%;
  }
  button {
    background: var(--btn-bg);
    color: var(--text);
    border: none;
    padding: 12px 18px;
    border-radius: 10px;
    font-size: 16px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.05s ease;
    font-family: inherit;
  }
  button:hover { background: var(--btn-bg-hover); }
  button:active { transform: translateY(1px); }
  button.primary {
    background: var(--accent);
    color: #1a1f2e;
    font-weight: 600;
  }
  button.primary:hover { background: #ffdd85; }
  .nav-row { display: flex; gap: 10px; flex: 1; min-width: 240px; }
  .nav-row button {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px 14px;
  }
  .btn-arrow {
    width: 20px;
    height: 20px;
    display: inline-block;
  }
  .btn-arrow.updown {
    display: inline-flex;
    width: auto;          /* let the two child SVGs determine width (~36px), not the 20px from .btn-arrow */
    gap: 0;
  }
  .btn-arrow.updown svg {
    width: 18px;
    height: 18px;
  }
  button.small {
    padding: 5px 12px;
    font-size: 14px;
    font-weight: 500;
    opacity: 0.75;
  }
  button.small:hover { opacity: 1; }
  .utility-buttons {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    /* Match the row above (category-selector / controls): full body-width up to 560px,
       so `justify-content: space-between` actually has room to push the buttons apart. */
    width: 100%;
    max-width: 560px;
    display: flex;
    justify-content: space-between;
    gap: 8px;
  }
  /* Shown only inside the Capacitor native shell (see app.js init()). */
  .native-only { display: none; }
  .native .native-only { display: inline-flex; }
  /* Hide on native; visible by default on web. */
  .native .web-only { display: none; }
  /* Page-level scroll IS allowed on native (so controls below the fold remain reachable
     if content overflows). The .card-container has `touch-action: none` (see native
     overrides at end of file) so dragging on the card itself never bubbles up as a
     scroll — vertical drags on the card stay reserved for the flip gesture. */
  html.native,
  html.native body {
    min-height: 100vh;
    min-height: 100dvh;
    overscroll-behavior: none;
  }
  .category-selector {
    margin-top: 132px;
    margin-bottom: 22px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 15px;
    color: var(--muted);
  }
  .category-selector label {
    /* The dropdown is self-explanatory — the "CATEGORY" label was visual clutter
       to the left of the centered dropdown. Hidden everywhere; the mobile rule
       below used to also hide it, now redundant. */
    display: none;
  }
  .category-selector select {
    background: rgba(255,255,255,0.1);
    color: var(--text);
    border: 1px solid rgba(255,255,255,0.15);
    border-radius: 8px;
    padding: 8px 30px 8px 12px;
    font-size: 16px;
    font-family: inherit;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff' opacity='0.7'><path d='M7 10l5 5 5-5z'/></svg>");
    background-repeat: no-repeat;
    background-position: right 6px center;
    background-size: 18px;
    transition: background-color 0.15s ease, border-color 0.15s ease;
  }
  .category-selector select:hover {
    background-color: rgba(255,255,255,0.18);
    border-color: rgba(255,255,255,0.25);
  }
  .category-selector select:focus {
    outline: none;
    border-color: var(--accent);
  }
  .category-selector select option {
    background: #1a1f2e;
    color: var(--text);
  }
  /* Star toggle (bottom-right) and Trash toggle (bottom-left) — always visible,
     tappable buttons that flip the card's starred / archived state. Each button
     holds two SVGs (outline + filled); the active one is revealed via CSS based
     on the card's .starred / .archived class. The buttons sit on both faces so
     the user can toggle either state regardless of which side is up. */
  .card-star-toggle,
  .card-trash-toggle {
    position: absolute;
    bottom: 14px;
    width: 40px;
    height: 40px;
    padding: 0;
    background: transparent;
    border: none;
    cursor: pointer;
    display: block;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
    /* Strip every "this is a button" indicator the browser/WebView paints on
       press: WebKit tap-highlight rectangle (touch), focus outline (rectangle
       around a focused button), and the UA appearance / box-shadow that
       Android Chrome's WebView applies to <button> by default. Without
       appearance:none + -webkit-appearance:none, Android still painted a
       rectangular background around the icon when the button was active. */
    -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none;
    appearance: none;
    outline: none;
    box-shadow: none;
  }
  .card-star-toggle:focus,
  .card-trash-toggle:focus,
  .card-star-toggle:focus-visible,
  .card-trash-toggle:focus-visible,
  .card-star-toggle:active,
  .card-trash-toggle:active {
    outline: none;
    background: transparent;
    box-shadow: none;
  }
  .card-star-toggle  { right: 14px; }
  .card-trash-toggle { left: 14px; }
  .card-star-toggle svg,
  .card-trash-toggle svg { width: 100%; height: 100%; }
  /* Default: show outline, hide filled. Outline reads as muted (low-opacity white)
     so an unstarred / unarchived card doesn't look like it's in a special state. */
  .card-star-toggle  .star-icon-filled,
  .card-trash-toggle .trash-icon-filled { display: none; }
  .card-star-toggle  .star-icon-outline  { display: block; color: rgba(255, 255, 255, 0.45); }
  .card-trash-toggle .trash-icon-outline { display: block; color: rgba(255, 255, 255, 0.45); }
  /* When the card carries the active state class, swap to the filled glyph in its
     accent color (gold for starred, soft red for archived). */
  .card.starred  .card-star-toggle .star-icon-outline   { display: none; }
  .card.starred  .card-star-toggle .star-icon-filled    { display: block; color: #f5c518; }
  .card.archived .card-trash-toggle .trash-icon-outline { display: none; }
  .card.archived .card-trash-toggle .trash-icon-filled  { display: block; color: #ef9a9a; }
  /* Reference cards (informational single-sided cards) can't be starred or archived,
     so hide both toggles to keep their face uncluttered. */
  .card.reference .card-star-toggle,
  .card.reference .card-trash-toggle { display: none; }

  /* Archived cards: diagonal hatched overlay on top of the existing face background.
     Applied to .card.archived (both faces), so the indicator shows whichever side is up. */
  .card.archived .card-face::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background-image: repeating-linear-gradient(
      45deg,
      rgba(255,255,255,0.10) 0,
      rgba(255,255,255,0.10) 2px,
      transparent 2px,
      transparent 12px
    );
  }
  /* Empty-state card (no cards in the active category — e.g. all archived). Hide
     the flip hint and back face since neither is meaningful, and dim the surface
     so it reads as inert. */
  .card.empty { cursor: default; }
  .card.empty .card-back { display: none; }
  .card.empty .flip-hint { display: none; }
  .card.empty .phrase {
    font-size: clamp(16px, 2.6vw, 19px);
    font-weight: 500;
    color: rgba(255,255,255,0.75);
    line-height: 1.4;
    max-width: 90%;
  }

  /* Long-press / right-click action menu. Full-viewport backdrop dims the page;
     the menu itself is centered with the card title at the top and stacked buttons. */
  .card-menu-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 24px;
  }
  .card-menu-backdrop[hidden] { display: none; }
  .card-menu {
    background: #2c3e50;
    color: var(--text);
    border-radius: 14px;
    padding: 16px;
    max-width: 360px;
    width: 100%;
    box-shadow: 0 20px 60px rgba(0,0,0,0.5);
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .card-menu-title {
    font-size: 18px;
    font-weight: 600;
    text-align: center;
    padding: 6px 8px 12px;
    border-bottom: 1px solid rgba(255,255,255,0.12);
    margin-bottom: 4px;
    word-break: break-word;
  }
  .card-menu-item {
    appearance: none;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.14);
    color: var(--text);
    border-radius: 10px;
    padding: 12px 16px;
    font-size: 15px;
    font-family: inherit;
    text-align: center;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease;
  }
  .card-menu-item:hover { background: rgba(255,255,255,0.12); border-color: rgba(255,255,255,0.24); }
  .card-menu-item:active { transform: translateY(1px); }
  /* Menu items with an inline icon switch to flex layout so the icon sits to the
     left of the label. Plain-text items (no .card-menu-icon child) keep the original
     centered text-only layout. */
  .card-menu-item:has(.card-menu-icon) {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
  }
  .card-menu-item .card-menu-icon { width: 18px; height: 18px; flex-shrink: 0; }

  /* Reference cards (Overview / grammar / pronunciation): single-sided, with bullet list. */
  .card.reference { cursor: default; }
  .card.reference .card-back { display: none; }
  .card.reference .card-front .phrase {
    font-size: clamp(18px, 3.2vw, 22px);
    font-weight: 600;
    margin: 4px 0 12px;
    line-height: 1.3;
  }
  .card.reference .flip-hint { display: none; }
  /* On the back of a card with an example sentence, hide the flip-hint(s) — the
     example is the prominent content and the hint just adds noise at the bottom. */
  .card-back.has-example .flip-hint { display: none; }
  .ref-bullets {
    list-style: none;
    padding: 0;
    margin: 0;
    font-size: 15px;
    line-height: 1.55;
    text-align: left;
    color: rgba(255,255,255,0.92);
    max-width: 92%;
    align-self: center;
  }
  .ref-bullets:empty { display: none; }
  .ref-bullets li {
    padding: 3px 0 3px 16px;
    position: relative;
  }
  .ref-bullets li::before {
    content: "•";
    position: absolute;
    left: 2px;
    color: var(--accent);
    opacity: 0.85;
  }
  .header-icons {
    /* 3-column grid: link icon (left) | centered middle group | settings gear (right).
       The 1fr outer columns make the middle group truly centered on the page rather
       than off-center toward the right edge the way `justify-content: space-between`
       (the previous flex layout) would leave it when link and settings have different
       visual weight. */
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    margin-bottom: 17px;
  }
  .header-icons > .header-icon-left { justify-self: start; }
  .header-icons > .settings-gear    { justify-self: end; }
  .header-icons-center {
    display: flex;
    align-items: center;
    gap: 18px;
    justify-self: center;
  }
  .header-icon {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: rgba(255,255,255,0.08);
    border: 1px solid rgba(255,255,255,0.12);
    color: var(--text);
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    /* Reset <button> user-agent padding so the SVG icon fills the circle the same way
       an <a class="header-icon"> would (the playback button is the only <button> here). */
    padding: 0;
    transition: background 0.15s ease, transform 0.4s ease, border-color 0.15s ease;
  }
  /* Author-origin `display: flex` above otherwise wins over the UA `[hidden]`
     rule (same specificity, author beats UA), so el.hidden=true wouldn't hide
     these. */
  .header-icon[hidden] { display: none; }
  .header-icon:hover {
    background: rgba(255,255,255,0.18);
    border-color: rgba(255,255,255,0.25);
  }
  .header-icon svg { width: 20px; height: 20px; }
  /* The recall-mode toggle is a text-labeled circle ("SV" / "EN") rather than an SVG icon. */
  .recall-mode-toggle {
    font: 600 12px / 1 inherit;
    letter-spacing: 0.5px;
    cursor: pointer;
  }
  /* The playback-mode toggle (manual / auto-speak / hands-free) shows a different
     icon per mode; the active mode-* class on the button reveals exactly one of the
     three .mode-icon SVGs inside. */
  .playback-mode-toggle { cursor: pointer; }
  .playback-mode-toggle .mode-icon { display: none; }
  .playback-mode-toggle.mode-manual     .mode-icon-manual,
  .playback-mode-toggle.mode-auto-speak .mode-icon-auto-speak,
  .playback-mode-toggle.mode-hands-free .mode-icon-hands-free { display: block; }
  .settings-gear:hover { transform: rotate(60deg); }
  .header-icon-left:hover { transform: translateX(-2px); }
  @media (max-width: 480px) {
    .card-container { height: 273px; }
    .controls { flex-direction: column; }
    .nav-row { width: 100%; }
    .header-icon { width: 34px; height: 34px; }
    /* Stretch the dropdown so its edges align with the Prev / Next buttons above. */
    .category-selector { width: 100%; max-width: 560px; }
    .category-selector select { flex: 1; width: 100%; }
  }
  /* Native (Capacitor) full-screen layout: minimal margins inside the device's
     safe-area insets; the card-container flex-grows to consume any remaining
     vertical space so the UI fills the screen instead of clustering at the top. */
  html.native body {
    padding: max(env(safe-area-inset-top), 8px)
             max(env(safe-area-inset-right), 12px)
             max(env(safe-area-inset-bottom), 8px)
             max(env(safe-area-inset-left), 12px);
  }
  .native header { margin-bottom: 10px; }
  .native h1 { margin-top: 0; }
  .native .subtitle { margin-bottom: 0; }
  .native .header-icons { margin-bottom: 13px; }
  .native .progress { margin: 10px 0 6px; }
  .native .progress-bar { margin-bottom: 12px; }
  .native .card-container {
    /* Adaptive height — larger on tall phones, but capped so the card never dominates
       the screen or pushes the controls (Prev/Flip/Next, Category, Reset/Shuffle)
       below the home indicator on iPhone. Previously 52vh / 460px, which overflowed
       on iPhone 15 Pro inside the safe-area insets. */
    height: clamp(243px, calc(46vh - 7px), 403px);
    flex: 0 0 auto;
    margin-bottom: 12px;
    /* The browser must not interpret touches on the card as a page scroll — the JS
       gesture handler owns vertical drags here (it commits a flip). Without this,
       enabling page scroll (above) would let a down-drag flip-AND-scroll, fighting
       the flip animation. */
    touch-action: none;
  }
  .native .category-selector { margin-top: 14px; margin-bottom: 0; }
  .native .utility-buttons { margin-top: 10px; padding-top: 10px; }
