  :root {
    /* Clean soft-dark palette — neutral, no muddy browns */
    --bg:        #0f0f11;
    --surface:   #17171c;
    --surface2:  #1e1e24;
    --surface3:  #26262e;
    --border:    #2e2e38;
    --border-hi: #42424f;

    /* Accent: fresh coral-peach */
    --accent:      #ffb4a0;
    --accent-dim:  rgba(255,180,160,0.12);
    --accent-glow: rgba(255,180,160,0.06);
    --accent-hover:#ffc9b8;

    /* Text — clean whites, no warm tint */
    --text:       #f2f2f4;
    --text-dim:   #8a8a9a;
    --text-muted: #4a4a58;

    /* Status colors — vivid, not muted */
    --green:  #6ee89a;
    --yellow: #ffd166;
    --red:    #ff7070;
    --blue:   #7eb8e8;

    /* Posters: one value, so a badge clipped by its container lines up with the
       art no matter which surface it is on. Tiny thumbs get the smaller one. */
    --poster-radius:    6px;
    --poster-radius-sm: 4px;

    --radius:    12px;
    --radius-sm: 7px;
    --radius-xs: 4px;
  }

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

  body {
    font-family: 'DM Sans', sans-serif;
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    font-size: 14px;
    line-height: 1.5;
  }

  /* ── SCROLLBARS ──
     Every scrollable surface gets the same 4px accent pill: page, modals,
     catalog dropdown, textareas. Mouse-driven devices only — gated on pointer
     capability, not width, because a tablet can be 1024px+ and still be
     touch-only. Touch keeps the native overlay bar, which fades on its own and
     reserves no width. */
  @media (hover: hover) and (pointer: fine) {
    ::-webkit-scrollbar { width: 4px; height: 4px; }
    ::-webkit-scrollbar-track { background: transparent; }
    ::-webkit-scrollbar-thumb {
      background: var(--accent);
      border-radius: 999px;
      min-height: 26px;
    }
    /* Scrollbars aren't clipped to border-radius, so on rounded containers the
       track is inset by the corner radius or the bar runs past the corner. */
    .modal::-webkit-scrollbar-track { margin: 18px 0; }
    .catalog-dropdown::-webkit-scrollbar-track { margin: 10px 0; }

    /* Firefox only. Setting scrollbar-width in Chrome makes it ignore every
       ::-webkit-scrollbar rule above, widening the bar and squaring the thumb.
       scrollbar-color inherits, scrollbar-width does not. */
    @supports not selector(::-webkit-scrollbar) {
      html { scrollbar-color: var(--accent) transparent; }
      html, .modal, .catalog-dropdown, textarea, #print-sheet { scrollbar-width: thin; }
    }
  }

  /* ── AUTH ── */
  #auth-screen {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
    gap: 28px;
    background: radial-gradient(ellipse 60% 50% at 50% 0%, rgba(240,168,152,0.06) 0%, transparent 70%);
  }

  .auth-logo {
    font-family: 'Nunito', sans-serif;
    font-size: 40px;
    font-weight: 800;
    letter-spacing: -1.5px;
    color: var(--text);
  }
  .auth-logo span { color: var(--accent); }
  .auth-logo small {
    display: block;
    font-size: 13px;
    font-weight: 400;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    text-align: center;
    margin-top: -4px;
  }

  .auth-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 18px;
    padding: 36px 32px;
    max-width: 390px;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 18px;
    align-items: center;
    text-align: center;
  }

  .auth-card h2 {
    font-family: 'Nunito', sans-serif;
    font-size: 18px;
    font-weight: 700;
    color: var(--text);
  }

  .auth-card p {
    color: var(--text-dim);
    font-size: 13px;
    line-height: 1.6;
  }

  .btn-primary {
    background: var(--accent);
    color: #1a0e0a;
    border: none;
    padding: 12px 28px;
    border-radius: var(--radius-sm);
    font-family: 'Nunito', sans-serif;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
    width: 100%;
    letter-spacing: 0.2px;
  }
  .btn-primary:hover { background: var(--accent-hover); }
  .btn-primary:active { transform: scale(0.98); }

  .token-input-wrap {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 7px;
  }
  .token-input-wrap label {
    font-size: 12px;
    color: var(--text-dim);
    text-align: left;
  }
  .token-input-wrap input {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    padding: 10px 14px;
    width: 100%;
    outline: none;
    transition: border-color 0.15s;
  }
  .token-input-wrap input:focus { border-color: var(--accent); }

  .divider {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--text-muted);
    font-size: 11px;
  }
  .divider::before, .divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border);
  }

  /* ── APP ── */
  #app { display: none; flex-direction: column; min-height: 100vh; }

  /* HEADER */
  header {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 0 20px;
    height: 68px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 100;
  }

  .header-logo {
    cursor: pointer;
    font-family: 'Nunito', sans-serif;
    font-size: 20px;
    font-weight: 800;
    letter-spacing: -0.5px;
    color: var(--text);
  }
  .header-logo span { color: var(--accent); }

  .header-right {
    display: flex;
    align-items: center;
    gap: 10px;
  }

  .user-chip {
    display: flex;
    align-items: center;
    gap: 7px;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 3px 11px 3px 3px;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-dim);
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
  }
  .user-chip:hover, .user-menu-wrap.open .user-chip { color: var(--text); border-color: var(--accent); }

  .user-menu-wrap { position: relative; }

  .user-menu {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 200px;
    padding: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(0,0,0,0.5);
    z-index: 200;
  }
  .user-menu-wrap.open .user-menu { display: block; }

  .user-menu button {
    display: block;
    width: 100%;
    padding: 9px 12px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.1s;
  }
  .user-menu button:hover { background: var(--surface2); }

  .user-menu-sep { height: 1px; margin: 4px 0; background: var(--border); }

  .user-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--surface3);
  }


  /* TABS */
  .tabs-wrap {
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    position: sticky;
    top: 68px;
    z-index: 90;
  }
  .tabs-wrap::-webkit-scrollbar { display: none; }

  .tabs {
    display: flex;
    padding: 10px 16px 0;
    min-width: max-content;
    gap: 2px;
  }

  .tab {
    padding: 7px 16px;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    border: 1px solid transparent;
    border-bottom: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.15s, background 0.15s;
    font-family: 'DM Sans', sans-serif;
    white-space: nowrap;
    letter-spacing: 0.1px;
  }
  .tab.active {
    background: var(--surface);
    border-color: var(--border);
    color: var(--text);
  }
  .tab:not(.active):hover { color: var(--text-dim); }

  /* Top is a global ranking, not a slice of the list — a rule sets it apart
     from the status tabs, and it takes the accent when active. */
  .tab-sep {
    width: 1px;
    background: var(--border);
    margin: 4px 9px 6px;
    flex-shrink: 0;
  }
  .tab-top { color: var(--text-muted); }
  .tab-top.active { color: var(--accent); }

  /* ── TOP ── */
  .top-filters {
    display: none;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 10px 20px;
  }
  .top-filters.open { display: block; }

  /* Arrows are the desktop affordance — a mouse can't drag the strip. Gated on
     pointer capability, not width, so an iPad keeps the touch behaviour. */
  .year-strip { display: flex; align-items: center; gap: 6px; min-width: 0; }
  .year-arrow { display: none; }
  @media (hover: hover) and (pointer: fine) {
    /* With arrows to page through it, the strip doesn't need the full width —
       a narrow well reads as a control rather than a band across the page. */
    .year-strip { max-width: 33%; min-width: 300px; }

    .year-arrow {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      width: 26px;
      height: 26px;
      background: var(--surface2);
      border: 1px solid var(--border);
      border-radius: 50%;
      color: var(--text-dim);
      font-size: 15px;
      line-height: 1;
      cursor: pointer;
      font-family: 'DM Sans', sans-serif;
      transition: border-color 0.15s, color 0.15s, opacity 0.15s;
    }
    .year-arrow:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
    .year-arrow:disabled { opacity: 0.3; cursor: default; }
  }

  .chips {
    display: flex;
    gap: 6px;
    align-items: center;
    overflow-x: auto;
    padding-bottom: 2px;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
  }
  .chips::-webkit-scrollbar { display: none; }

  .chip {
    padding: 5px 11px;
    border-radius: 20px;
    border: 1px solid var(--border);
    background: none;
    color: var(--text-dim);
    font-size: 12px;
    font-weight: 600;
    font-family: 'DM Sans', sans-serif;
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
  }
  .chip:hover { border-color: var(--border-hi); color: var(--text); }
  /* a single year picked */
  .chip.on { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
  /* every year is covered because "all years" is active — outlined, not filled */
  .chip.lit { border-color: var(--accent); color: var(--accent); }
  /* the default view, held apart from the years. 2px even when idle so
     selecting it never shifts the row. */
  .chip-all { padding: 7px 15px; font-size: 13px; border-width: 2px; margin-right: 4px; }
  .chip-all.on { border-color: var(--accent); background: var(--accent-dim); }

  .top-heading {
    margin-top: 8px;
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
  }

  #search-input.global-search { border-color: var(--accent); }

  .top-list { display: flex; flex-direction: column; gap: 2px; }

  .top-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 6px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background 0.12s;
  }
  .top-row:hover { background: var(--surface2); }
  /* brief wash when a search result jumps to its row */
  .top-row.found { animation: topFound 2s ease-out; }
  @keyframes topFound {
    0%, 40% { background: var(--accent-dim); }
    100%    { background: transparent; }
  }
  @media (prefers-reduced-motion: reduce) {
    .top-row.found { animation: none; background: var(--accent-dim); }
  }

  .top-rank {
    width: 36px;
    flex-shrink: 0;
    text-align: center;
    font-family: 'Nunito', sans-serif;
    font-weight: 800;
    font-size: 19px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
  }
  .top-rank.top3 { color: var(--accent); }


  .top-info { flex: 1; min-width: 0; }
  .top-title {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .top-meta { font-size: 11px; color: var(--text-muted); margin-top: 3px; }

  /* flex blockifies the inline .catalog-add span, so margin-top applies and its
     vertical padding doesn't overflow the line box. */
  .top-add { display: flex; margin-top: 7px; }

  .top-score {
    flex-shrink: 0;
    background: var(--surface3);
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    color: var(--yellow);
    font-size: 12.5px;
    font-weight: 700;
    padding: 3px 8px;
    font-variant-numeric: tabular-nums;
  }

  .top-more {
    margin: 14px auto 4px;
    display: block;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 600;
    padding: 9px 22px;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s;
  }
  .top-more:not(:disabled):hover { border-color: var(--accent); color: var(--accent); }

  /* A width query, not a pointer one: this is about horizontal room, not input.
     At 360px the 81px cover left the title 121px and truncated 17 of 50 rows
     against 5 before; trimming the cover and rank buys most of that back. */
  @media (max-width: 400px) {
    .top-row   { gap: 9px; }
    .top-rank  { width: 28px; font-size: 17px; }
    .poster-md { width: 72px; height: 104px; }
  }

  /* CONTROLS */
  .controls {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 10px 20px;
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
  }

  .search-wrap {
    position: relative;
    flex: 1;
    min-width: 180px;
    max-width: 380px;
  }
  .search-wrap input {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    padding: 7px 12px 7px 32px;
    width: 100%;
    outline: none;
    transition: border-color 0.15s;
  }
  .search-wrap input::placeholder { color: var(--text-muted); }
  .search-wrap input:focus { border-color: var(--accent); }

  .search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    font-size: 15px;
    pointer-events: none;
    line-height: 1;
  }

  .catalog-dropdown {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    z-index: 200;
    max-height: 360px;
    overflow-y: auto;
    box-shadow: 0 12px 32px rgba(0,0,0,0.5);
  }

  .catalog-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
    transition: background 0.1s;
  }
  .catalog-item:last-child { border-bottom: none; }
  .catalog-item:hover { background: var(--surface2); }


  .catalog-info { flex: 1; min-width: 0; }
  .catalog-title {
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text);
  }
  .catalog-meta {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 1px;
  }

  /* the name the query matched, under the displayed one */
  .catalog-original {
    font-size: 11px;
    color: var(--text-dim);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .catalog-warn {
    font-size: 11px;
    color: var(--red);
    margin-top: 1px;
  }

  .top-find-text {
    font-size: 13.5px;
    color: var(--text-dim);
    line-height: 1.6;
  }

  .catalog-add {
    background: var(--accent-dim);
    border: 1px solid var(--accent);
    border-radius: var(--radius-xs);
    color: var(--accent);
    font-size: 11px;
    font-weight: 700;
    padding: 3px 8px;
    cursor: pointer;
    white-space: nowrap;
    font-family: 'DM Sans', sans-serif;
    transition: background 0.12s;
    flex-shrink: 0;
  }
  .catalog-add:hover { background: var(--accent); color: #1a0e0a; }
  .catalog-add.in-list { background: transparent; border-color: var(--border); color: var(--text-muted); cursor: default; }

  .catalog-loading {
    padding: 16px;
    text-align: center;
    color: var(--text-muted);
    font-size: 13px;
  }

  .search-mode-hint {
    font-size: 10px;
    color: var(--text-muted);
    padding: 7px 12px 4px;
    border-bottom: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .search-mode-hint button {
    background: none;
    border: none;
    color: var(--accent);
    font-size: 11px;
    cursor: pointer;
    font-family: 'DM Sans', sans-serif;
    padding: 0;
  }

  select.filter-select {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    padding: 7px 10px;
    outline: none;
    cursor: pointer;
    transition: border-color 0.15s;
  }
  select.filter-select:focus { border-color: var(--accent); }

  .toggle-group {
    display: flex;
    gap: 2px;
    margin-left: auto;
  }
  .toggle-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 600;
    padding: 6px 10px;
    cursor: pointer;
    font-family: 'DM Sans', sans-serif;
    transition: all 0.15s;
  }
  .toggle-btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
  .toggle-btn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
  .toggle-btn.active { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }

  /* MAIN */
  main {
    padding: 18px 20px;
    flex: 1;
  }

  /* On desktop the list scrolls inside <main> rather than the page scrolling.
     Two reasons: the header then spans the full window width instead of
     stopping short at the scrollbar gutter, and the scrollbar starts at the
     top of the scrollable region instead of behind the sticky header.
     Touch is left alone — phones keep normal page scrolling. */
  @media (hover: hover) and (pointer: fine) {
    #app { height: 100dvh; overflow: hidden; }
    main { overflow-y: auto; min-height: 0; }
  }

  /* STATS */
  .stats-bar {
    display: flex;
    gap: 10px;
    margin-bottom: 18px;
    flex-wrap: wrap;
  }
  .stat-chip {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 4px 14px;
    font-size: 12px;
    color: var(--text-dim);
    font-weight: 500;
  }
  .stat-chip strong { color: var(--accent); font-weight: 700; margin-right: 4px; }

  /* ── LIST ── */
  .anime-list { display: flex; flex-direction: column; gap: 0; }

  /* SERIES GROUP (multi-season) */
  .series-group {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 8px;
    transition: border-color 0.2s;
  }
  .series-group:hover { border-color: var(--border-hi); }

  .series-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    cursor: pointer;
    user-select: none;
  }


  .series-info { flex: 1; min-width: 0; }

  .series-title {
    font-family: 'Nunito', sans-serif;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text);
  }

  .series-meta {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 5px;
    flex-wrap: wrap;
  }

  .season-count {
    font-size: 11px;
    color: var(--text-muted);
    background: var(--surface3);
    padding: 2px 8px;
    border-radius: 10px;
    font-weight: 600;
  }

  .series-score-avg {
    font-size: 12px;
    font-weight: 700;
    color: var(--yellow);
    display: flex;
    align-items: center;
    gap: 3px;
  }

  .chevron {
    color: var(--text-muted);
    font-size: 11px;
    transition: transform 0.2s;
    flex-shrink: 0;
  }
  .series-group.open .chevron { transform: rotate(90deg); }

  .seasons-list { border-top: 1px solid var(--border); }

  /* SEASON ROW inside group */
  .season-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    border-bottom: 1px solid var(--border);
    transition: background 0.12s;
  }
  .season-row:last-child { border-bottom: none; }
  .season-row:hover { background: var(--surface2); }


  .season-info { flex: 1; min-width: 0; }

  .season-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-dim);
    white-space: normal;
    line-height: 1.3;
  }

  .season-submeta {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 3px;
    flex-wrap: wrap;
  }

  /* STANDALONE ROW */
  .standalone-row {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    margin-bottom: 8px;
    transition: border-color 0.2s;
  }
  .standalone-row:hover { border-color: var(--border-hi); }


  .standalone-info { flex: 1; min-width: 0; }
  .standalone-title {
    font-family: 'Nunito', sans-serif;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text);
  }
  .standalone-meta {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 4px;
    flex-wrap: wrap;
  }

  /* STATUS BADGES */
  .status-badge {
    font-size: 10px;
    font-weight: 700;
    padding: 2px 7px;
    border-radius: 8px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }
  .status-CURRENT   { background: rgba(130,212,160,0.15); color: var(--green); }
  .status-COMPLETED { background: rgba(144,188,216,0.15); color: var(--blue); }
  .status-PLANNING  { background: rgba(240,168,152,0.15); color: var(--accent); }
  .status-DROPPED   { background: rgba(232,120,120,0.15); color: var(--red); }
  .status-PAUSED    { background: rgba(240,200,120,0.15); color: var(--yellow); }

  .progress-text {
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 500;
  }

  /* PROGRESS BAR */
  .progress-bar-wrap {
    width: 100%;
    height: 3px;
    background: var(--surface3);
    border-radius: 2px;
    margin-top: 6px;
    overflow: hidden;
  }
  .progress-bar-fill {
    height: 100%;
    background: var(--accent);
    border-radius: 2px;
    transition: width 0.3s;
    opacity: 0.7;
  }

  /* SEASON/STANDALONE ACTIONS */
  .season-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
  }

  .score-badge {
    background: var(--surface3);
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    color: var(--yellow);
    font-size: 12px;
    font-weight: 700;
    padding: 3px 7px;
    min-width: 32px;
    text-align: center;
  }
  .score-badge.no-score { color: var(--text-muted); font-weight: 400; }

  .btn-plus {
    background: var(--accent-dim);
    border: 1px solid var(--accent);
    border-radius: var(--radius-xs);
    color: var(--accent);
    cursor: pointer;
    font-size: 15px;
    font-weight: 700;
    width: 28px;
    height: 28px;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.12s;
    flex-shrink: 0;
  }
  .btn-plus:hover { background: var(--accent); color: #1a0e0a; }
  .btn-plus:active { transform: scale(0.92); }

  .btn-sm {
    background: var(--surface3);
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    color: var(--text-muted);
    cursor: pointer;
    font-size: 13px;
    padding: 4px 8px;
    font-family: 'DM Sans', sans-serif;
    transition: all 0.12s;
    white-space: nowrap;
  }
  .btn-sm:hover { color: var(--text-dim); border-color: var(--border-hi); }

  /* ── MODAL ── */
  .modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(10,8,6,0.75);
    z-index: 200;
    align-items: center;
    justify-content: center;
    padding: 20px;
    backdrop-filter: blur(3px);
  }
  .modal-overlay.open { display: flex; }

  .modal {
    background: var(--surface);
    border: 1px solid var(--border-hi);
    border-radius: 18px;
    width: 100%;
    max-width: 460px;
    max-height: 90vh;
    /* overflow-x must be explicit: a non-visible value on one axis computes the
       other to `auto`, which iOS treats as pannable and rubber-bands sideways. */
    overflow: hidden auto;
    display: flex;
    flex-direction: column;
    box-shadow: 0 24px 60px rgba(0,0,0,0.6);
  }


  .modal-header {
    padding: 18px 18px 14px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: flex-start;
    gap: 14px;
  }

  .modal-cover {
    width: 48px;
    height: 68px;
    object-fit: cover;
    border-radius: 6px;
    background: var(--surface3);
    flex-shrink: 0;
  }

  .modal-title-wrap { flex: 1; min-width: 0; }
  .modal-title {
    font-family: 'Nunito', sans-serif;
    font-size: 16px;
    font-weight: 800;
    line-height: 1.3;
    color: var(--text);
  }
  .modal-subtitle {
    font-size: 12px;
    color: var(--text-dim);
    margin-top: 3px;
  }

  /* The original name under a translated one — there to check the translation
     against, so it stays quieter than the meta line and is hidden when the
     title on screen is already the original. */
  .modal-original {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 2px;
    line-height: 1.35;
  }
  .modal-original:empty { display: none; }

  /* Romaji sits under the English one: useful for checking a translation and
     for recognising a title that was never released under an English name,
     but it is the least-wanted of the three, so it is the quietest. */
  .modal-romaji {
    font-size: 11.5px;
    color: var(--text-muted);
    opacity: 0.75;
    margin-top: 1px;
    line-height: 1.35;
  }
  .modal-romaji:empty { display: none; }

  .btn-close {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--text-dim);
    cursor: pointer;
    font-size: 14px;
    width: 26px;
    height: 26px;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    transition: all 0.12s;
  }
  .btn-close:hover { color: var(--text); border-color: var(--border-hi); }

  .modal-body { padding: 18px; display: flex; flex-direction: column; gap: 16px; }

  .field-group { display: flex; flex-direction: column; gap: 7px; }
  .field-label {
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
  }

  .score-row {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
  }

  .score-btn {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-xs);
    border: 1px solid var(--border);
    background: var(--surface2);
    color: var(--text-dim);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.12s;
    font-family: 'DM Sans', sans-serif;
  }
  .score-btn:hover { border-color: var(--accent); color: var(--accent); }
  .score-btn.active { background: var(--accent); border-color: var(--accent); color: #1a0e0a; }

  .status-row {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
  }

  .status-btn {
    padding: 5px 12px;
    border-radius: 20px;
    border: 1px solid var(--border);
    background: var(--surface2);
    color: var(--text-dim);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.12s;
    font-family: 'DM Sans', sans-serif;
  }
  .status-btn.active-CURRENT   { background: rgba(130,212,160,0.15); border-color: var(--green); color: var(--green); }
  .status-btn.active-COMPLETED { background: rgba(144,188,216,0.15); border-color: var(--blue); color: var(--blue); }
  .status-btn.active-PLANNING  { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
  .status-btn.active-DROPPED   { background: rgba(232,120,120,0.15); border-color: var(--red); color: var(--red); }
  .status-btn.active-PAUSED    { background: rgba(240,200,120,0.15); border-color: var(--yellow); color: var(--yellow); }

  .progress-row {
    display: flex;
    align-items: center;
    gap: 7px;
  }
  .progress-row input[type=number] {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
    padding: 7px 10px;
    width: 76px;
    outline: none;
    text-align: center;
    transition: border-color 0.15s;
  }
  .progress-row input:focus { border-color: var(--accent); }
  .progress-row span { color: var(--text-dim); font-size: 13px; }

  .btn-prog {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    color: var(--text-dim);
    cursor: pointer;
    font-size: 16px;
    font-weight: 700;
    width: 32px;
    height: 32px;
    display: flex; align-items: center; justify-content: center;
    transition: border-color 0.15s, color 0.15s;
  }
  .btn-prog:hover { border-color: var(--accent); color: var(--accent); }

  textarea.notes-input {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    padding: 10px 12px;
    width: 100%;
    resize: vertical;
    min-height: 76px;
    outline: none;
    transition: border-color 0.15s;
  }
  textarea.notes-input:focus { border-color: var(--accent); }

  #export-modal .modal { max-width: 560px; }
  .export-picks { margin-bottom: 12px; }
  textarea.export-text {
    height: 50vh;
    resize: none;
    font-size: 12.5px;
    line-height: 1.5;
  }

  .modal-footer {
    padding: 14px 18px;
    border-top: 1px solid var(--border);
    display: flex;
    gap: 7px;
    justify-content: flex-end;
  }

  /* this one can carry three actions at once; the others never do */
  #top-find-modal .modal-footer { flex-wrap: wrap; }

  .btn-save {
    background: var(--accent);
    color: #1a0e0a;
    border: none;
    padding: 8px 20px;
    border-radius: var(--radius-sm);
    font-family: 'Nunito', sans-serif;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s;
  }
  .btn-save:hover { background: var(--accent-hover); }

  #info-edit-btn { margin-right: auto; }

  .btn-cancel {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 8px 16px;
    border-radius: var(--radius-sm);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    cursor: pointer;
    transition: border-color 0.15s;
  }
  .btn-cancel:hover { border-color: var(--border-hi); }

  .btn-delete {
    background: rgba(232,120,120,0.10);
    border: 1px solid var(--red);
    color: var(--red);
    padding: 8px 14px;
    border-radius: var(--radius-sm);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    cursor: pointer;
    transition: background 0.15s;
    margin-right: auto;
  }
  .btn-delete:hover { background: rgba(232,120,120,0.22); }

  /* LOADING */
  .loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 80px 24px;
    gap: 14px;
    color: var(--text-dim);
    font-size: 13px;
  }

  .spinner {
    width: 32px;
    height: 32px;
    border: 2.5px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 0.75s linear infinite;
  }

  @keyframes spin { to { transform: rotate(360deg); } }

  .empty-state {
    text-align: center;
    padding: 56px 24px;
    color: var(--text-muted);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    font-size: 13px;
  }
  .empty-img { width: 96px; height: 96px; object-fit: contain; opacity: 0.5; }
  .empty-state > div:not(.icon) { max-width: 360px; line-height: 1.5; }
  .load-retry { margin-top: 8px; }
  .empty-state > .icon { font-size: 30px; line-height: 1; }
  .empty-state > .load-down {
    font-family: 'Nunito', sans-serif;
    font-size: 22px;
    font-weight: 700;
    color: var(--text);
  }

  /* TOAST */
  #toast {
    position: fixed;
    bottom: 22px;
    right: 22px;
    background: var(--surface2);
    border: 1px solid var(--border-hi);
    border-radius: var(--radius);
    padding: 10px 16px;
    font-size: 13px;
    color: var(--text);
    opacity: 0;
    transform: translateY(8px);
    transition: all 0.2s;
    z-index: 999;
    pointer-events: none;
    font-weight: 500;
  }
  #toast.show { opacity: 1; transform: translateY(0); }

  /* INFO MODAL */
  #info-modal .modal { max-width: 520px; }

  .info-cover-lg {
    width: 100%;
    max-height: 220px;
    object-fit: cover;
    border-radius: var(--radius) var(--radius) 0 0;
    display: block;
  }

  .info-meta-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 8px 0;
  }

  .info-score {
    background: var(--surface3);
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    color: var(--yellow);
    font-size: 13px;
    font-weight: 700;
    padding: 3px 9px;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.2;
  }
  .score-label {
    font-size: 9px;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    margin-top: 2px;
  }

  /* Looks exactly like the plain score box it replaced. It is a button only so
     touch can tap it, so the browser's own button look, tap flash and click
     focus ring are all switched off. Only touch gets a caret: a mouse opens it
     by hovering, and there tapping is the only way in. */
  .score-main {
    font-family: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    -webkit-tap-highlight-color: transparent;
  }
  .score-main:focus:not(:focus-visible) { outline: none; }
  .score-caret { display: none; }
  /* the exact opposite of canHover in app.js, so every device gets one of the two */
  @media not all and (hover: hover) and (pointer: fine) {
    .score-caret {
      display: inline-block;
      margin-left: 4px;
      font-size: 9px;
      color: var(--text-muted);
      transition: transform 0.2s;
    }
    .score-main[aria-expanded="true"] .score-caret { transform: rotate(180deg); }
  }

  /* Fixed and outside the modal, so the modal's scrolling can't clip it. It
     grows out of the corner nearest the box: from the top when it opens below,
     from the bottom when there was only room above. Closed, it stays laid out
     (opacity, not display) so its size can be measured before it is placed. */
  .score-pop {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 2000;
    width: 270px;
    padding: 12px 14px;
    background: var(--surface2);
    border: 1px solid var(--border-hi);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(0,0,0,0.5);
    opacity: 0;
    transform: translateY(-4px) scale(0.97);
    transform-origin: top left;
    pointer-events: none;
    transition: opacity 0.16s ease-out, transform 0.16s ease-out;
  }
  .score-pop.above { transform: translateY(4px) scale(0.97); transform-origin: bottom left; }
  .score-pop.open { opacity: 1; transform: none; pointer-events: auto; }
  /* Touch opens the sources in the panel instead. It grows from 0fr to 1fr,
     which animates to the content's real height — max-height would need a
     guessed number and ease against the wrong size. */
  .score-inline {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows 0.2s ease, opacity 0.2s ease;
  }
  .score-inline.open { grid-template-rows: 1fr; opacity: 1; }
  .score-inline-inner { overflow: hidden; min-height: 0; }
  .score-inline-inner > :first-child { margin-top: 4px; }
  .score-inline-inner > :last-child { margin-bottom: 12px; }
  @media (prefers-reduced-motion: reduce) {
    .score-pop, .score-inline, .score-caret { transition: none; }
  }
  .score-table {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr);
    gap: 4px 14px;
    align-items: baseline;
    font-size: 13px;
  }
  .score-src { color: var(--text-dim); }
  .score-val { color: var(--yellow); font-weight: 700; }
  .score-votes { color: var(--text-muted); font-size: 12px; }
  .score-dist-label {
    margin: 12px 0 6px;
    font-size: 11px;
    color: var(--text-muted);
  }

  .info-link {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 4px 11px;
    transition: border-color 0.15s, background 0.15s;
  }
  .info-link:hover { border-color: var(--accent); background: var(--accent-dim); }

  .genre-chip {
    background: var(--accent-dim);
    border-radius: 20px;
    color: var(--accent);
    font-size: 11px;
    font-weight: 600;
    padding: 2px 9px;
  }

  .info-desc {
    font-size: 13px;
    color: var(--text-dim);
    line-height: 1.65;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .info-desc.expanded {
    display: block;
  }

  /* pre-wrap keeps the author's line breaks without turning 
 into markup;
     anywhere is required because the desktop left column is a fixed 220px
     track that a pasted URL would otherwise overflow. */
  .info-notes-text {
    font-size: 13px;
    color: var(--text-dim);
    line-height: 1.6;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  /* Hikka's synopsis is plain text with real line breaks; AniList's is HTML.
     pre-line keeps the breaks without letting stray spacing through. */
  .desc-ua { white-space: pre-line; }

  .info-desc-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }

  .info-desc-toggle {
    background: none;
    border: none;
    color: var(--accent);
    font-size: 12px;
    cursor: pointer;
    padding: 2px 0;
    font-family: 'DM Sans', sans-serif;
    margin-top: 3px;
  }

  .related-section { margin-top: 10px; }
  .related-title {
    font-size: 11px;
    color: var(--text-muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin-bottom: 8px;
  }

  .related-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
  }
  .related-item:last-child { border-bottom: none; }
  .related-item:hover { background: var(--surface2); border-radius: var(--radius-xs); padding-left: 4px; }


  .related-info { flex: 1; min-width: 0; }
  .related-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .related-type-label {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
  }
  .related-in-list-badge {
    font-size: 10px;
    font-weight: 700;
    background: var(--accent-dim);
    border: 1px solid var(--accent);
    border-radius: 8px;
    color: var(--accent);
    padding: 2px 7px;
    flex-shrink: 0;
  }

  /* STUDIO */
  .studio-row { display: flex; flex-wrap: wrap; gap: 7px; }
  .studio-group { margin-bottom: 10px; }

  .studio-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 4px 12px 4px 4px;
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
  }
  .studio-chip:hover { border-color: var(--accent); background: var(--accent-dim); }

  /* The monogram tile, shown until a logo resolves and left in place when none
     does. .is-lg is the studio modal's header version of the same mark. */
  .studio-mono {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--surface3);
    color: var(--accent);
    font-family: 'Nunito', sans-serif;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.3px;
    flex-shrink: 0;
  }
  .studio-mono.is-lg {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    font-size: 15px;
  }

  /* Every logo is dark against a dark surface, so all of them are turned white.
     This deliberately drops the brand colour: a light plate behind them keeps it
     but puts white cards in a dark UI, and invert+hue-rotate only yields pastel.

     Why not a plain brightness(0) invert(1): Wikipedia's fair-use logos are
     often opaque JPEGs — a white rectangle with dark art on it — and whitening
     those paints a solid white block. Inverting to greyscale and compositing
     with `screen` drops whatever is darkest to the backdrop, so an opaque white
     ground falls away and only the mark itself lights up. Transparent PNG and
     SVG come out the same as before. */
  .studio-logo-img {
    display: block;
    height: 18px;
    width: auto;
    max-width: 160px;
    object-fit: contain;
    filter: grayscale(1) invert(1) contrast(1.5) brightness(1.15);
    mix-blend-mode: screen;
  }

  /* A wordmark already says the name, so it replaces the monogram and the
     label both, rather than sitting next to a second copy of the name. */
  .has-logo > .studio-mono, .has-logo > .studio-name { display: none; }
  .studio-chip.has-logo { padding: 6px 13px; gap: 0; }

  .studio-logo-wrap { flex-shrink: 0; display: flex; align-items: center; }
  .studio-logo-wrap .studio-logo-img { height: 30px; max-width: 210px; }

  #studio-modal .modal { max-width: 760px; }

  .studio-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
    gap: 14px 12px;
  }

  .studio-card { cursor: pointer; min-width: 0; }

  .studio-card-art {
    position: relative;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--surface3);
    transition: transform 0.15s, box-shadow 0.15s;
  }
  .studio-card:hover .studio-card-art {
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0,0,0,0.45);
  }


  .studio-card-score {
    transition: opacity 0.15s;
    position: absolute;
    left: 5px;
    bottom: 5px;
    background: rgba(10,8,6,0.82);
    border-radius: 10px;
    color: var(--yellow);
    font-size: 10px;
    font-weight: 700;
    padding: 2px 6px;
  }
  .studio-card-badge {
    position: absolute;
    top: 5px;
    right: 5px;
    background: var(--accent);
    border-radius: 8px;
    color: #1a0e0a;
    font-size: 9px;
    font-weight: 800;
    padding: 2px 6px;
  }


  .studio-card-name {
    font-size: 12px;
    font-weight: 500;
    color: var(--text);
    line-height: 1.35;
    margin-top: 6px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .studio-card-meta { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

  .studio-more { align-self: center; }

  /* Two outbound links in a 220px column, so they wrap rather than overflow. */
  .link-row { display: flex; flex-wrap: wrap; gap: 6px; }

  /* UKRAINIAN DUB */
  /* Two slots are always in the markup and the width picks one: portrait shows
     the folded badge after the description, landscape the open block in the
     left column. 649.98/650 rather than 649/650 — a fractional viewport lands
     between the two and would match neither. */
  @media (min-width: 650px)    { .dub-portrait  { display: none; } }
  @media (max-width: 649.98px) { .dub-landscape { display: none; } }

  .dub-row { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }

  .dub-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 4px 12px 4px 4px;
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 12.5px;
    text-decoration: none;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
  }
  .dub-chip:hover { border-color: var(--accent); background: var(--accent-dim); }
  .dub-chip.is-plain { cursor: default; }
  .dub-chip.is-plain:hover { border-color: var(--border); background: var(--surface2); }

  /* AniHub's team logos are square avatars, not the wide wordmarks the
     production studios have — so a round tile, never a wide slot. */
  .dub-logo, .dub-mono {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--surface3);
    flex-shrink: 0;
  }
  .dub-logo { object-fit: cover; display: block; }
  .dub-mono {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    font-family: 'Nunito', sans-serif;
    font-size: 10px;
    font-weight: 800;
  }

  /* The badge states the fact and is the control, so it has to survive being
     pressed — .field-group is a flex column, and a lone button in one stretches
     the full width and stops reading as a chip. */
  .dub-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    align-self: flex-start;
    background: rgba(110,232,154,0.12);
    border: 1px solid var(--green);
    border-radius: 20px;
    color: var(--green);
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    font-weight: 700;
    padding: 4px 11px;
  }
  .dub-badge.none {
    background: var(--surface2);
    border-color: var(--border);
    color: var(--text-muted);
  }
  .dub-toggle { cursor: pointer; gap: 7px; }
  .dub-caret { font-size: 9px; opacity: 0.8; }

  .dub-more {
    background: none;
    border: 1px dashed var(--border-hi);
    border-radius: 20px;
    color: var(--text-dim);
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    padding: 5px 12px;
    cursor: pointer;
  }
  .dub-more:hover { border-color: var(--accent); color: var(--accent); }

  /* The count and the merge note are subordinate to whatever heads the block,
     so they shed the label's caps and tracking. */
  .dub-note {
    font-size: 11px;
    font-weight: 400;
    color: var(--text-muted);
    text-transform: none;
    letter-spacing: 0;
    margin-left: 7px;
  }

  /* SEQUEL SUGGESTION MODAL */
  /* Below the other overlays so the info modal can open on top of it. */
  #sequel-modal { z-index: 190; }
  #sequel-modal .modal { max-width: 400px; }
  #sequel-modal .modal-header { padding-bottom: 0; border-bottom: none; gap: 10px; }

  .sequel-cards {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    gap: 16px;
  }

  .sequel-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1;
    min-width: 0;
  }

  .sequel-card-main {
    display: flex;
    align-items: stretch;
    gap: 14px;
  }

  /* Right-hand column: name and meta sit directly beside the cover they
     describe, with the buttons pushed to the bottom of the same column. */
  .sequel-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1;
    min-width: 0;
  }
  .sequel-body .sequel-actions { margin-top: auto; }

  /* .poster.… because .poster-fluid's width: 100% comes later in the file and
     would win at equal specificity — on a phone that stretched the cover across
     the modal and pushed the title and buttons off its right edge. */
  .poster.sequel-cover-link {
    overflow: hidden;
    display: block;
    position: relative;
    width: 110px;
    flex-shrink: 0;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: outline-color 0.15s;
    outline: 2px solid transparent;
  }
  .sequel-cover-link:hover { outline-color: var(--accent); }

  /* Unaired sequel: dim the top of the poster and label it. Hovering the
     poster clears both so the art can be seen. */
  /* ── POSTERS ──
     One system decides what a poster is: the box, the corner, and the unaired
     treatment. Surfaces pick a size and nothing else. The container clips, so
     the badge and the date never carry a radius of their own — that mismatch
     is what used to leave a sliver at the corners. */
  .poster {
    position: relative;
    flex-shrink: 0;
    line-height: 0;
    overflow: hidden;
    border-radius: var(--poster-radius);
    background: var(--surface3);
  }
  .poster-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .poster:hover .cover-status,
  .poster:hover .poster-date { opacity: 0; }

  .poster-xs { width: 28px;  height: 40px;  border-radius: var(--poster-radius-sm); }
  .poster-sm { width: 38px;  height: 54px;  border-radius: var(--poster-radius-sm); }
  .poster-md { width: 81px;  height: 117px; }
  .poster-lg { width: 90px;  height: 129px; }
  .poster-xl { width: 108px; height: 156px; }
  /* fills its column and keeps the poster ratio — grids and the info card */
  .poster-fluid { width: 100%; aspect-ratio: 2 / 3; }

  /* «Очікується» at 14px cannot fit a row thumbnail, so the same treatment
     scales with the box rather than being skipped there. */
  .poster-xs .cover-status, .poster-sm .cover-status,
  .poster-md .cover-status, .poster-lg .cover-status {
    font-size: 9px; padding: 5px 2px 0; letter-spacing: 0;
  }
  .poster-xs .poster-date, .poster-sm .poster-date,
  .poster-md .poster-date, .poster-lg .poster-date {
    font-size: 8.5px; padding: 0 2px 4px; letter-spacing: 0;
  }
  /* Only one of the two labels is ever shown; the size picks it. */
  .status-short { display: none; }

  /* Thumbnails: same gradient in the same place, but the short word — the full
     one needs 49px on a line and gets 24 here, which lands at 3px type. The
     date goes too; there is no room for a second line under it. */
  .poster-xs .cover-status,
  .poster-sm .cover-status {
    padding: 3px 2px 0;
    letter-spacing: 0;
    white-space: nowrap;
  }
  .poster-xs .status-full,
  .poster-sm .status-full { display: none; }
  .poster-xs .status-short,
  .poster-sm .status-short { display: inline; }
  .poster-xs .cover-status { font-size: 7px; }
  .poster-sm .cover-status { font-size: 9px; }
  .poster-xs .poster-date,
  .poster-sm .poster-date { display: none; }

  .cover-status {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 58%;
    padding: 10px 3px 0;
    background: linear-gradient(to bottom,
      rgba(10,8,6,0.97) 0%,
      rgba(10,8,6,0.92) 32%,
      rgba(10,8,6,0.64) 64%,
      rgba(10,8,6,0) 100%);
    color: var(--accent);
    font-size: 14px;
    font-weight: 700;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    text-align: center;
    pointer-events: none;
    transition: opacity 0.15s;
  }
  /* The date is the status badge's mirror at the foot of the poster: same
     gradient flipped, and it leaves on hover alongside it so the art comes
     back whole. Inside the poster, so the card keeps every other card's shape. */
  .poster-date {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 46%;
    padding: 0 4px 8px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: linear-gradient(to top,
      rgba(10,8,6,0.97) 0%,
      rgba(10,8,6,0.92) 32%,
      rgba(10,8,6,0.64) 64%,
      rgba(10,8,6,0) 100%);
    color: var(--accent);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.25;
    text-align: center;
    pointer-events: none;
    transition: opacity 0.15s;
  }

  .sequel-cover-link:hover .cover-status,
  .sequel-cover-link:hover .poster-date,
  .studio-card-art:hover .cover-status,
  .studio-card-art:hover .poster-date { opacity: 0; }


  .sequel-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }

  .sequel-name {
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .sequel-meta { font-size: 11px; color: var(--text-muted); }

  .sequel-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
  }
  .sequel-actions-global { margin-top: 4px; align-items: center; }
  .sequel-actions-global .btn-sequel-no { width: auto; min-width: 160px; }

  .btn-sequel-add,
  .btn-sequel-no {
    width: 100%;
    border-radius: var(--radius-sm);
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
    font-weight: 600;
    padding: 11px 16px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
  }

  .btn-sequel-add {
    background: var(--accent);
    border: 1px solid var(--accent);
    color: var(--bg);
  }
  .btn-sequel-add:not(:disabled):hover { background: var(--accent-dim); color: var(--accent); }
  .btn-sequel-add.in-list,
  .btn-sequel-add:disabled {
    background: var(--surface3);
    border-color: var(--border);
    color: var(--text-muted);
    cursor: default;
  }

  .btn-sequel-no {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-dim);
  }
  .btn-sequel-no:hover { border-color: var(--text-muted); color: var(--text); }

  .sequel-card > .info-link {
    align-self: center;
    background: none;
    font-family: 'DM Sans', sans-serif;
    cursor: pointer;
  }

  .sequel-and {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    align-self: center;
    flex-shrink: 0;
  }

  @media (min-width: 650px) {
    .sequel-cards { flex-direction: row; align-items: flex-start; }
    .poster.sequel-cover-link { width: 130px; }
    #sequel-modal .modal.multi { max-width: 700px; }
  }

  /* ── TRAILER ──
     Not an embed until you ask for one: the thumbnail is our own markup, and
     the player only replaces it on click. overflow:hidden clips YouTube to the
     card's rounded box so it reads as part of the panel. */
  .trailer-section { margin-top: 12px; }

  .trailer-card {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    overflow: hidden;
    background: var(--surface3);
    cursor: pointer;
    transition: border-color 0.15s;
  }

  .trailer-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }

  .trailer-veil {
    position: absolute;
    inset: 0;
    background: linear-gradient(to top,
      rgba(10,8,6,0.75) 0%, rgba(10,8,6,0.15) 55%, rgba(10,8,6,0) 100%);
  }

  .trailer-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(10,8,6,0.72);
    border: 2px solid var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    padding-left: 4px;
    transition: background 0.15s, color 0.15s;
  }
  /* Drawn, not typed — iOS renders U+25B6 as a colour emoji. */
  .trailer-play::before {
    content: '';
    border-style: solid;
    border-width: 9px 0 9px 15px;
    border-color: transparent transparent transparent currentColor;
  }

  /* Hover styling only where a pointer can actually hover. On iOS an element
     carrying hover rules spends the first tap showing that state, which is why
     the card needed tapping twice to start. */
  @media (hover: hover) and (pointer: fine) {
    .trailer-card:hover { border-color: var(--accent); }
    .trailer-card:hover .trailer-play { background: var(--accent); color: var(--bg); }
  }

  .trailer-label {
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: 10px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
  }
  .trailer-label a { color: var(--accent); text-decoration: none; flex-shrink: 0; }

  .trailer-fs {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 1;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-sm);
    background: rgba(10,8,6,0.55);
    border: 1px solid rgba(255,255,255,0.14);
    color: var(--text);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    /* Touch keeps it faintly visible: there is no hover to bring it back, and
       the iframe takes every tap that lands on it, so hiding it would strand it. */
    opacity: 0.3;
    transition: opacity 0.25s, background 0.15s, border-color 0.15s, color 0.15s;
  }
  /* Full strength for a moment when playback starts. */
  .trailer-card.fs-peek .trailer-fs { opacity: 1; }

  @media (hover: hover) and (pointer: fine) {
    /* A pointer can bring it back, so out of the way entirely until hovered. */
    .trailer-fs { opacity: 0; pointer-events: none; }
    .trailer-card:hover .trailer-fs,
    .trailer-card.fs-peek .trailer-fs { opacity: 1; pointer-events: auto; }
    .trailer-fs:hover { background: var(--accent); border-color: var(--accent); color: var(--bg); }
  }

  .trailer-card iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
  }

  /* SCORE DISTRIBUTION GRAPH */
  .score-dist {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 60px;
    padding-bottom: 18px;
  }
  .dist-bar-wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    cursor: default;
  }
  .dist-bar {
    width: 100%;
    min-height: 2px;
    background: var(--accent);
    border-radius: 2px 2px 0 0;
    transition: opacity 0.15s;
  }
  .dist-bar-wrap:hover .dist-bar { opacity: 0.6; }
  .dist-tick {
    font-size: 9px;
    color: var(--text-muted);
    margin-top: 3px;
    line-height: 1;
  }

  /* INFO MODAL COLUMNS (tablet/desktop via @media below) */
  .info-col-left, .info-col-right { display: block; }
  .info-col-left { margin-bottom: 4px; }

  /* RESPONSIVE */
  @media (max-width: 600px) {
    header, .controls, main { padding-left: 14px; padding-right: 14px; }
    .tabs { padding-left: 12px; }
    .auth-card { padding: 24px 18px; }
  }

  @media (min-width: 650px) {
    #info-modal .modal { max-width: 800px; }
    #info-body {
      display: grid;
      grid-template-columns: 220px minmax(0, 1fr);
      gap: 20px;
      align-items: start;
    }
    .info-cover-lg { max-height: 320px; border-radius: var(--radius); }
    .info-col-left { margin-bottom: 0; }
    .info-col-left > .info-notes { margin-top: 12px; }
  }

  /* A phone in landscape is wide enough for the two-column layout but only
     ~340px tall, where a 320px cover leaves no room for anything else.
     Keyed on height, so portrait phones and desktops are untouched. */
  @media (max-height: 480px) {
    .info-cover-lg { max-height: 190px; }
  }

  /* Phone: uncropped poster on the left, the compact chips beside it, and
     everything wide (graph, description, related) full width underneath.
     display: contents flattens the two desktop columns into this grid so the
     desktop layout above stays untouched. */
  /* 649.98, not 649: a fractional viewport (browser zoom, some DPRs) lands
     between 649 and 650, where neither this nor the min-width:650 block below
     matches and the modal loses both layouts. Measured at 649.6157px. */
  @media (max-width: 649.98px) {
    #info-body {
      display: grid;
      grid-template-columns: 130px minmax(0, 1fr);
      gap: 16px 14px;
      align-items: start;
    }
    .info-col-left, .info-col-right { display: contents; }
    .info-col-left > *, .info-col-right > * { grid-column: 1 / -1; }
    .info-col-left > .info-cover-lg {
      grid-column: 1;
      grid-row: 1;
      max-height: none;
      aspect-ratio: 2 / 3;
      border-radius: var(--radius);
    }
    .info-col-right > .info-meta-row {
      grid-column: 2;
      grid-row: 1;
      margin: 0;
      align-items: flex-start;
      align-content: flex-start;
    }
    .info-col-left > .info-link { order: 1; justify-self: start; }
    .trailer-section { order: 2; }
    .info-col-left > .info-notes { order: 3; }
  }

  /* ── PDF EXPORT ── */
  /* On screen it is a full-window preview at A4 width, so what you see is what
     prints; some browsers (the desktop app's own pane among them) save straight
     to file with no preview of their own. Browsers drop backgrounds when printing
     unless told otherwise, which would leave light text on white paper —
     print-color-adjust keeps the dark theme. */
  #print-sheet {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 500;
    background: var(--bg);
    overflow: hidden auto;
  }
  #print-sheet.open { display: block; }

  .ps-bar {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 12px 20px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
  }
  .ps-bar-title {
    flex: 1;
    min-width: 0;
    font-family: 'Nunito', sans-serif;
    font-size: 15px;
    font-weight: 800;
  }
  .ps-page { max-width: 210mm; margin: 0 auto; padding: 12mm 11mm; }
  /* Chrome writes a gradient that fades to transparent into the PDF as a pink
     wash over the whole cover; a flat translucent fill, like the score badge,
     comes out right. So the unaired label and date sit on bands here — in the
     preview too, so it still shows what will print. */
  #print-sheet .cover-status, #print-sheet .poster-date {
    height: auto;
    padding: 6px 4px;
    background: rgba(10,8,6,0.82);
  }
  /* Paper can't be hovered, so the preview must not clear the label either. */
  #print-sheet .poster:hover .cover-status,
  #print-sheet .poster:hover .poster-date { opacity: 1; }

  @media print {
    @page { size: A4; margin: 0; }
    html, body {
      background: var(--bg) !important;
      -webkit-print-color-adjust: exact;
      print-color-adjust: exact;
    }
    body > :not(#print-sheet) { display: none !important; }
    #print-sheet { display: block; position: static; overflow: visible; }
    .ps-bar { display: none; }
    .ps-page {
      max-width: none;
      /* repeats the padding on every page, not just the first and last */
      -webkit-box-decoration-break: clone;
      box-decoration-break: clone;
    }
  }

  .ps-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding-bottom: 14px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--border);
  }
  .ps-logo { height: 64px; object-fit: contain; }
  .ps-head-text { flex: 1; min-width: 0; }
  .ps-name {
    font-family: 'Nunito', sans-serif;
    font-size: 28px;
    font-weight: 800;
    line-height: 1.2;
  }
  .ps-date { font-size: 14px; color: var(--text-dim); }
  .ps-stats .stat-chip { font-size: 13px; }
  .ps-stats { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; }

  .ps-section { margin-bottom: 22px; }
  .ps-sec-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    break-after: avoid;
  }
  .ps-sec-head .status-badge { font-size: 14px; padding: 4px 12px; }
  .ps-count { font-size: 15px; font-weight: 700; color: var(--text-dim); }

  .ps-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 18px 14px;
  }
  .ps-card { break-inside: avoid; min-width: 0; }
  /* Titles are never cut: on paper there is no hover or tap to reveal the rest. */
  .ps-title {
    margin-top: 7px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    overflow-wrap: anywhere;
  }
  .ps-meta {
    margin-top: 2px;
    font-size: 11.5px;
    color: var(--text-dim);
  }
  .ps-score {
    position: absolute;
    top: 6px;
    right: 6px;
    padding: 2px 7px;
    border-radius: var(--radius-xs);
    background: rgba(10,8,6,0.82);
    color: var(--yellow);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.4;
  }
