/* =========================================================
   WonderCalendar – styles

   The theme depends on the active categories (data-theme on <html>):
     film   = only Film       -> movie theatre (velvet and brass)
     tv     = only TV Series  -> midnight blue with glows
     anime  = only Anime      -> pop, colorful, hard borders
     blend  = two or three    -> palette computed in JS as a mix of the selected
                                 themes (see computeBlend in app.js). The values
                                 below are the neutral starting point; JS overrides
                                 them as inline custom properties on <html>.
   ========================================================= */

/* ---------- Fonts (self-hosted, variable). Files: assets/fonts/ ---------- */
@font-face {
  font-family: "Anybody"; font-style: normal; font-weight: 100 900;
  font-stretch: 50% 150%;
  font-display: swap;
  src: url("fonts/anybody-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Anybody"; font-style: normal; font-weight: 100 900;
  font-stretch: 50% 150%;
  font-display: swap;
  src: url("fonts/anybody-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans"; font-style: normal; font-weight: 400 700;
  font-display: swap;
  src: url("fonts/instrument-sans-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Sans"; font-style: normal; font-weight: 400 700;
  font-display: swap;
  src: url("fonts/instrument-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens ---------- */
:root {
  color-scheme: light;

  --ff-display: "Anybody", "Arial Narrow", system-ui, sans-serif;
  --ff-body: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* personality of headings: changes with the theme thanks to the variable font */
  --stretch: 100%;
  --w-display: 800;
  --tt: none;
  --ls: -0.01em;

  --radius: 14px;
  --radius-s: 9px;
  --bw: 1px;
  --gutter: clamp(0.9rem, 2vw, 1.5rem);
  --maxw: 110rem;

  /* brand colors (logo): never change */
  --k-film: #e2531f;
  --k-tv: #4d8bff;
  --k-anime: #ff4f9a;

  /* neutral / blend base */
  --bg: #f6f7fb;
  --surface: #ffffff;
  --surface-2: #eceff6;
  --ink: #12172b;
  --ink-2: #4a5270;
  --line: #d6dbe8;
  --accent: #12172b;
  --on-accent: #ffffff;
  --focus: #2d4bff;
  --c-film: #d9480f;
  --c-tv: #2e6be6;
  --c-anime: #d62a7e;
  --shadow: 0 1px 2px rgb(18 23 43 / 0.06), 0 10px 24px -14px rgb(18 23 43 / 0.25);
  --hero-bg: var(--surface);
  --hero-line: var(--line);

  /* opacity of the decorative background layers (one per theme) */
  --o-film: 0;
  --o-tv: 0;
  --o-anime: 0;
}

[data-theme="film"] {
  color-scheme: dark;
  --stretch: 62%;
  --w-display: 700;
  --tt: uppercase;
  --ls: 0.02em;
  --radius: 5px;
  --radius-s: 3px;

  --bg: #17080c;
  --surface: #231016;
  --surface-2: #301a22;
  --ink: #f4e8d3;
  --ink-2: #c4ae98;
  --line: #4d2c36;
  --accent: #e3b04b;
  --on-accent: #2a1408;
  --focus: #f1c35f;
  --c-film: #e3b04b;
  --c-tv: #e3b04b;
  --c-anime: #e3b04b;
  --shadow: 0 14px 30px -16px #000;
  --hero-bg: linear-gradient(135deg, #34151f, #1d0c12);
  --hero-line: rgb(227 176 75 / 0.55);
  --o-film: 1;
}

[data-theme="tv"] {
  color-scheme: dark;
  --stretch: 100%;
  --w-display: 600;
  --tt: none;
  --ls: -0.025em;
  --radius: 18px;
  --radius-s: 11px;

  --bg: #080d1c;
  --surface: #111a33;
  --surface-2: #19243f;
  --ink: #e7edff;
  --ink-2: #a3b3d9;
  --line: #27375f;
  --accent: #52d6f4;
  --on-accent: #04222c;
  --focus: #7be3fa;
  --c-film: #52d6f4;
  --c-tv: #52d6f4;
  --c-anime: #52d6f4;
  --shadow: 0 0 0 1px rgb(82 214 244 / 0.08), 0 18px 34px -18px rgb(82 214 244 / 0.35);
  --hero-bg: linear-gradient(135deg, #17234a, #0e1630 60%, #1b1a4d);
  --hero-line: rgb(82 214 244 / 0.4);
  --o-tv: 1;
}

[data-theme="anime"] {
  color-scheme: light;
  --stretch: 135%;
  --w-display: 900;
  --tt: none;
  --ls: -0.01em;
  --radius: 16px;
  --radius-s: 11px;
  --bw: 2px;

  --bg: #ffe3f1;
  --surface: #ffffff;
  --surface-2: #fff1b8;
  --ink: #1c0f3a;
  --ink-2: #53407d;
  --line: #1c0f3a;
  --accent: #ff4f9a;
  --on-accent: #1c0f3a;
  --focus: #5b2dff;
  --sticker: #ffd23f;
  --c-film: #ff4f9a;
  --c-tv: #ff4f9a;
  --c-anime: #ff4f9a;
  --hard: var(--ink); /* offset "sticker" shadows */
  --shadow: 4px 4px 0 var(--hard);
  --hero-bg: var(--sticker);
  --hero-line: var(--ink);
  --o-anime: 1;
}


/* =========================================================
   Day / night (html[data-mode]).
   Night keeps Movies and TV as they have always been (dark) and gives Anime darker, violet tints.
   Day keeps Anime as it has always been (light) and gives Movies a lighter, yellowish look and TV a
   lighter, light-blue one. Blends of several categories follow the mode too (see computeBlend).
   ========================================================= */
html[data-mode="day"][data-theme="film"] {
  color-scheme: light;
  --bg: #fdf2d0; --surface: #fffaea; --surface-2: #f7e5a8;
  --ink: #2b1a05; --ink-2: #6b5124; --line: #e3cb8a;
  --accent: #9a5b00; --on-accent: #fffaf0; --focus: #b36b00;
  --c-film: #9a5b00; --c-tv: #9a5b00; --c-anime: #9a5b00;
  --shadow: 0 1px 2px rgb(80 50 0 / 0.08), 0 12px 26px -14px rgb(130 85 0 / 0.38);
  --hero-bg: linear-gradient(135deg, #fff3c4, #ffe08a);
  --hero-line: rgb(154 91 0 / 0.5);
}
html[data-mode="day"][data-theme="tv"] {
  color-scheme: light;
  --bg: #e3f2fc; --surface: #ffffff; --surface-2: #d2e9f8;
  --ink: #0b1c36; --ink-2: #3d5a82; --line: #b5d3ea;
  --accent: #0a6a8f; --on-accent: #ffffff; --focus: #0a6a8f;
  --c-film: #0a6a8f; --c-tv: #0a6a8f; --c-anime: #0a6a8f;
  --shadow: 0 1px 2px rgb(10 60 100 / 0.08), 0 12px 26px -16px rgb(10 100 160 / 0.4);
  --hero-bg: linear-gradient(135deg, #d7ecfb, #c4e2f7 60%, #d5defa);
  --hero-line: rgb(10 106 143 / 0.4);
}
html[data-mode="night"][data-theme="anime"] {
  color-scheme: dark;
  /* "Deep amethyst" with orchid panels: a dark violet page (never neon, never dull), panels that lean slightly
     to magenta, soft text and lines so it stays easy on the eyes in the dark. The big panels are frosted
     glass (below). */
  --bg: #170d2e; --surface: #2d1848; --surface-2: #3e2262;
  --ink: #eee8fa; --ink-2: #b9a8e6; --line: #6a55b4; --hard: #0b0618;
  --accent: #f0a0cf; --on-accent: #26123f; --focus: #ffe3a3; --sticker: #4a2a72;
  --c-film: #ee96c8; --c-tv: #ee96c8; --c-anime: #ee96c8;
  --hero-bg: linear-gradient(135deg, rgb(142 98 196 / 0.48), rgb(100 68 156 / 0.36));
  --hero-line: rgb(214 188 240 / 0.34);
}
/* Frosted glass (Anime, night): translucent panels that blur the balls behind them. Dialogs, menus and
   toasts keep the opaque --surface, so their text never sits on a busy background. */
html[data-mode="night"][data-theme="anime"] :is(.cell, .hero, .day) {
  -webkit-backdrop-filter: blur(10px) saturate(1.05); backdrop-filter: blur(10px) saturate(1.05);
}
html[data-mode="night"][data-theme="anime"] :is(.cell, .day) {
  background: color-mix(in srgb, var(--surface) 58%, transparent);
  border-color: rgb(214 188 240 / 0.28);
}
html[data-mode="night"][data-theme="anime"] .cell:is(:hover, .is-selected) { background: color-mix(in srgb, var(--surface-2) 66%, transparent); }
/* category colors of the badges / heat spots: lighter on dark surfaces, darker on light ones */
html[data-mode="day"]:is([data-theme="film"], [data-theme="tv"]) :is(.sug, .dlg, #saved) { --t-film: #d9480f; --t-tv: #2e6be6; --t-anime: #d62a7e; }
html[data-mode="night"][data-theme="anime"] :is(.sug, .dlg, #saved) { --t-film: #ff7a45; --t-tv: #5b9bff; --t-anime: #ee96c8; }
html[data-mode="day"]:is([data-theme="film"], [data-theme="tv"]) #year { --h-film: #d9480f; --h-tv: #2e6be6; --h-anime: #d62a7e; }
html[data-mode="night"][data-theme="anime"] #year { --h-film: #ff7a45; --h-tv: #5b9bff; --h-anime: #ee96c8; }
html[data-mode="day"] .d-film { background: radial-gradient(90% 60% at 50% -15%, rgb(255 205 90 / 0.5), transparent 65%), radial-gradient(80% 50% at 50% 115%, rgb(255 236 170 / 0.5), transparent 70%); }
html[data-mode="day"] .d-film::after { opacity: 0.07; }
html[data-mode="day"] .d-tv { background: radial-gradient(60rem 28rem at 88% -8%, rgb(120 190 255 / 0.4), transparent 65%), radial-gradient(44rem 26rem at -8% 8%, rgb(110 220 245 / 0.35), transparent 65%); }
/* the background balls and dots: calmer at night (pastel, not neon) */
html[data-mode="night"] .deco-anime .ball { opacity: 0.27; filter: saturate(0.55); }
html[data-mode="night"] .deco-anime .halftone { opacity: 0.3; }

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { height: 100%; scrollbar-gutter: stable; /* same width in Calendar (no scroll) and Timeline: nothing shifts */ -webkit-text-size-adjust: 100%; background: var(--bg); transition: background-color 0.45s ease; }
body {
  margin: 0;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  isolation: isolate;
  font-family: var(--ff-body);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.45s ease, color 0.45s ease;
}
/* Calendar view: the whole app fits the viewport, nothing scrolls the page */
body.view-calendar { height: 100vh; height: 100dvh; overflow: hidden; }
body.view-timeline { min-height: 100vh; min-height: 100dvh; }

button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
img { display: block; max-width: 100%; }
h1, h2, h3, h4 { margin: 0; line-height: 1.05; }
h1, h2, h3, .display {
  font-family: var(--ff-display);
  font-stretch: var(--stretch);
  font-weight: var(--w-display);
  text-transform: var(--tt);
  letter-spacing: var(--ls);
}
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

.sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: 1rem; top: -4rem; z-index: 100; padding: 0.6rem 1rem;
  background: var(--accent); color: var(--on-accent); border-radius: var(--radius-s); font-weight: 700;
}
.skip:focus { top: 1rem; }

main, .foot { width: min(var(--maxw), 100% - 2 * (var(--gutter) + var(--rail, 0px))); margin-inline: auto; }

/* =========================================================
   Decorative background
   .deco (Movies, TV): position: fixed => anchored to the viewport, it stays still while the
   content scrolls over it. Height uses the *large* viewport (lvh) so mobile bars do not make it jump.
   .deco-anime (Anime): anchored to the page; app.js sets its height to the page height and fills
   it with balls, so they scroll with the content.
   ========================================================= */
.deco {
  position: fixed; top: 0; left: 0; width: 100%; height: 100vh; height: 100lvh;
  z-index: -1; pointer-events: none; overflow: hidden;
}
.deco > i { position: absolute; inset: 0; transition: opacity 0.5s ease; }
.d-film { opacity: var(--o-film); }
.d-tv { opacity: var(--o-tv); }

.d-film {
  background:
    radial-gradient(90% 60% at 50% -15%, rgb(150 28 50 / 0.45), transparent 65%),
    radial-gradient(80% 50% at 50% 115%, rgb(0 0 0 / 0.55), transparent 70%);
}
.d-film::after {
  content: ""; position: absolute; inset: 0; opacity: 0.16; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .7 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.d-tv {
  background:
    radial-gradient(60rem 28rem at 88% -8%, rgb(124 92 255 / 0.32), transparent 65%),
    radial-gradient(44rem 26rem at -8% 8%, rgb(82 214 244 / 0.16), transparent 65%);
}
.deco-anime {
  position: absolute; top: 0; left: 0; width: 100%; z-index: -1;
  overflow: hidden; pointer-events: none;
  opacity: var(--o-anime); transition: opacity 0.5s ease;
}
.atile { position: absolute; left: 0; width: 100%; pointer-events: none; }
.ball { position: absolute; display: block; aspect-ratio: 1; border-radius: 50%; }
.halftone {
  position: absolute; inset: 0; display: block;
  background: radial-gradient(circle, rgb(255 79 154 / 0.3) 1.6px, transparent 1.9px) 0 0 / 16px 16px;
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent 75%);
  mask-image: linear-gradient(to bottom, #000, transparent 75%);
}

/* ---------- Header ---------- */
.top {
  position: relative; z-index: 30;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 0.6rem 1.25rem;
  padding: 0.8rem max(var(--gutter), calc((100% - var(--maxw)) / 2)) 0.7rem; /* the header stays full width: the ad banners sit below it */
}
body.view-timeline .top {
  position: sticky; top: 0;
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.brand {
  margin: 0;
  display: flex; align-items: center; gap: 0.6rem; white-space: nowrap; min-width: 0;
  font-size: clamp(1.3rem, 2.4vw, 1.75rem);
}
.brand-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* never collides with the view switch */
/* The name changes font with the theme (narrow capitals for Movies, wide and heavy for Anime). Its column
   always keeps the width of the widest one, so the buttons next to it do not slide when categories are
   switched. A hidden copy of the name in the widest style does the sizing (it has no height). */
.brand-text::after {
  content: "WonderCalendar"; content: "WonderCalendar" / "";
  display: block; height: 0; overflow: hidden; visibility: hidden; pointer-events: none;
  font-stretch: 135%; font-weight: 900; text-transform: none; letter-spacing: -0.01em;
}
.logo { flex: none; }
/* "Wonder": a holographic sweep of the three logo colors, played when the site opens and now and then
   (app.js adds .is-on). Only background-position of one small word is animated; at rest nothing runs. */
.holo.is-on {
  background-image: linear-gradient(100deg, currentColor 0 30%, var(--k-film) 38%, #ffd23f 44%, var(--k-tv) 52%, #7be3fa 57%, var(--k-anime) 63%, currentColor 71% 100%);
  background-size: 300% 100%; background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  animation: holo var(--holo-ms, 2.4s) ease-in-out 1;
}
@keyframes holo { from { background-position: 100% 0; } to { background-position: 0% 0; } }
@media (prefers-reduced-motion: reduce) { .holo.is-on { animation: none; background: none; -webkit-text-fill-color: currentColor; } }
.logo { --d: 0.7rem; display: inline-flex; align-items: center; gap: 4px; }
.logo i { width: var(--d); height: var(--d); border-radius: 999px; }
/* film and anime stretch into pills: film grows upwards, anime downwards, TV stays a dot; the dot
   itself keeps its place, so the header does not change height. Everything scales with --d. */
.logo i:nth-child(1) { height: calc(var(--d) * 1.98); transform: translateY(calc(var(--d) * -0.49)); }
.logo i:nth-child(3) { height: calc(var(--d) * 1.98); transform: translateY(calc(var(--d) * 0.49)); }
.logo i:nth-child(1) { background: var(--k-film); }
.logo i:nth-child(2) { background: var(--k-tv); }
.logo i:nth-child(3) { background: var(--k-anime); }

.controls {
  position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end;
  gap: 0.5rem 0.9rem; min-width: 0;
}
.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; }
/* "Show all" comes first in the markup, i.e. on the LEFT of the tags: the tags are anchored to the search box on the
   right, so when the button appears or disappears (all categories on) only the free space on its left changes and
   the tags stay where they are. On phones it goes back under them (order below). */
.chip {
  --cat: var(--c-film);
  display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.42rem 0.85rem 0.42rem 0.65rem;
  background: transparent; color: var(--ink-2); font-weight: 600; font-size: 0.92rem;
  border: var(--bw) solid var(--line); border-radius: 999px;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}
.chip[data-cat="tv"] { --cat: var(--c-tv); }
.chip[data-cat="anime"] { --cat: var(--c-anime); }
.chip .sw { width: 0.8rem; height: 0.8rem; border-radius: 50%; border: 2px solid var(--cat); background: transparent; }
.chip .n { font-weight: 500; font-variant-numeric: tabular-nums; opacity: 0.85; }
.chip[aria-pressed="true"] { background: var(--surface); color: var(--ink); border-color: var(--ink); }
.chip[aria-pressed="true"] .sw { background: var(--cat); }
.chip[aria-disabled="true"] { cursor: not-allowed; } /* the last active category cannot be switched off */
[data-theme="film"] .chip[aria-pressed="true"],
[data-theme="tv"] .chip[aria-pressed="true"] { border-color: var(--accent); }
[data-theme="anime"] .chip[aria-pressed="true"] { box-shadow: 2px 2px 0 var(--hard); }
.chip.nudge { animation: nudge 0.35s ease-out; }
@keyframes nudge { 20%, 60% { transform: translateX(-4px); } 40%, 80% { transform: translateX(4px); } }

.hint {
  position: absolute; left: 0; top: calc(100% + 0.35rem); z-index: 40; margin: 0; padding: 0.35rem 0.7rem;
  background: var(--ink); color: var(--bg); border-radius: var(--radius-s);
  font-size: 0.82rem; font-weight: 600; white-space: nowrap;
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}
.hint.show { opacity: 1; transform: none; }
.hint-search { left: auto; right: 0; } /* under the search bar, right-aligned so it never leaves the screen */

.search { position: relative; flex: 1 1 11rem; max-width: 18rem; }
.search > svg { position: absolute; left: 0.85rem; top: 50%; transform: translateY(-50%); color: var(--ink-2); pointer-events: none; }
.search input {
  width: 100%; height: 2.4rem; padding: 0 0.9rem 0 2.5rem;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: 999px;
}
.search input::placeholder { color: var(--ink-2); opacity: 0.9; }

/* Autocomplete dropdown. Left/width are set by positionSuggest() on desktop; on phones it is
   full width (see the max-width: 30rem block) and as tall as the room above the keyboard. */
.sug {
  position: absolute; top: calc(100% + 0.45rem); left: 0; z-index: 50; width: 26rem; max-width: calc(100vw - 1rem);
  max-height: min(var(--sug-max, 70vh), 28rem); overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
}
.sug-list { margin: 0; padding: 0.3rem; list-style: none; }
.sug-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.5rem;
  border-radius: var(--radius-s); transition: background-color 0.12s;
}
.sug-row.is-active { background: var(--surface-2); }
.sug-main {
  display: grid; gap: 0.25rem; min-width: 0; padding: 0.55rem 0.3rem 0.55rem 0.6rem;
  background: none; border: 0; text-align: left; border-radius: var(--radius-s);
}
.sug-title { font-weight: 700; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sug-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.5rem; color: var(--ink-2); font-size: 0.82rem; }
.sug-meta .badge { font-size: 0.7rem; padding-block: 0; }
.sug-date { font-variant-numeric: tabular-nums; }
.sug-go {
  height: 2rem; padding: 0 0.95rem; margin-right: 0.25rem; font-size: 0.82rem; font-weight: 700;
  background: var(--accent); color: var(--on-accent); border: var(--bw) solid var(--accent); border-radius: 999px;
}
.sug-go:hover { filter: brightness(1.1); }
[data-theme="anime"] .sug-go { border-color: var(--line); }
.sug-empty { padding: 0.8rem 0.8rem; color: var(--ink-2); font-size: 0.9rem; }

/* Under a single-category theme every --c-* is the theme colour, but the dropdown and the dialog can show
   titles of other categories: give their badges the real colour of each category. */
[data-theme="film"] :is(.sug, .dlg, #saved) { --t-film: #ff7a45; --t-tv: #5b9bff; --t-anime: #ff5fa6; }
[data-theme="tv"] :is(.sug, .dlg, #saved) { --t-film: #ff7a45; --t-tv: #5b9bff; --t-anime: #ff5fa6; }
[data-theme="anime"] :is(.sug, .dlg, #saved) { --t-film: #d9480f; --t-tv: #2e6be6; --t-anime: #d62a7e; }
:is([data-theme="film"], [data-theme="tv"], [data-theme="anime"]) :is(.sug, .dlg, #saved) :is(.badge, .poster)[data-cat="film"] { --cat: var(--t-film); }
:is([data-theme="film"], [data-theme="tv"], [data-theme="anime"]) :is(.sug, .dlg, #saved) :is(.badge, .poster)[data-cat="tv"] { --cat: var(--t-tv); }
:is([data-theme="film"], [data-theme="tv"], [data-theme="anime"]) :is(.sug, .dlg, #saved) :is(.badge, .poster)[data-cat="anime"] { --cat: var(--t-anime); }

/* "Go to" in the calendar: quick glow around the cell of the chosen day */
@keyframes cell-glow {
  0% { opacity: 1; box-shadow: 0 0 0 3px var(--accent), 0 0 26px 8px color-mix(in srgb, var(--accent) 75%, transparent); }
  100% { opacity: 0; box-shadow: 0 0 0 3px var(--accent), 0 0 46px 16px transparent; }
}
.cell.glow::after {
  content: ""; position: absolute; inset: -3px; border-radius: calc(var(--radius-s) + 3px); pointer-events: none;
  animation: cell-glow 0.95s ease-out;
}

/* one-off highlight of the title reached with "Go to" */
@keyframes flash {
  0%, 55% { box-shadow: 0 0 0 3px var(--accent), 0 0 18px 4px color-mix(in srgb, var(--accent) 55%, transparent); }
  100% { box-shadow: 0 0 0 3px transparent, 0 0 0 0 transparent; }
}
.flash { animation: flash 1.6s ease-out; }

/* Header, right side: view switch + saved titles */
.top-actions { display: flex; align-items: center; gap: 0.5rem; }
.saved-btn {
  position: relative; display: inline-grid; place-items: center; flex: none; width: 2.6rem; height: 2.6rem; padding: 0;
  background: var(--surface); color: var(--ink); border: var(--bw) solid var(--line); border-radius: 50%;
}
.saved-btn:hover { background: var(--surface-2); }
.saved-btn.has-saved svg path { fill: #e5233d; stroke: #e5233d; }
.saved-badge {
  position: absolute; top: -0.3rem; right: -0.3rem; min-width: 1.15rem; height: 1.15rem; padding: 0 0.25rem;
  display: grid; place-items: center; border-radius: 999px;
  background: #e5233d; color: #fff; font: 700 0.72rem/1 var(--ff-body); border: 2px solid var(--bg);
}

/* View switch: the active pill is a separate element that slides between the two options.
   html[data-view] is set by the inline script in <head> (no flash) and by render(). */
.seg {
  position: relative; isolation: isolate;
  display: inline-grid; grid-template-columns: 1fr 1fr; padding: 0.18rem; gap: 0.1rem;
  background: var(--surface); border: var(--bw) solid var(--line); border-radius: 999px;
}
.seg::before {
  content: ""; position: absolute; z-index: -1; top: 0.18rem; bottom: 0.18rem; left: 0.18rem;
  width: calc((100% - 0.36rem - 0.1rem) / 2);
  background: var(--accent); border-radius: 999px;
  transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s;
}
html[data-view="timeline"] .seg::before { transform: translateX(calc(100% + 0.1rem)); }
.seg button {
  border: 0; background: none; color: var(--ink-2); white-space: nowrap;
  padding: 0.4rem 0.95rem; border-radius: 999px; font-weight: 600; font-size: 0.9rem;
  transition: color 0.25s;
}
.seg button[aria-pressed="true"] { color: var(--on-accent); }

/* ---------- Buttons ---------- */
.icon-btn {
  display: inline-grid; place-items: center; width: 2.3rem; height: 2.3rem; padding: 0;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: 50%;
}
.icon-btn:hover:not(:disabled) { background: var(--surface-2); }
.icon-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.btn-s {
  height: 2.3rem; padding: 0 1rem; font-weight: 600; font-size: 0.9rem;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: 999px;
}
.btn-s:hover:not(:disabled) { background: var(--surface-2); }
.btn-s:disabled { opacity: 0.4; cursor: not-allowed; }
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.7rem 1.2rem; font-weight: 700; text-decoration: none;
  background: var(--accent); color: var(--on-accent);
  border: var(--bw) solid var(--accent); border-radius: 999px;
}
.btn:hover { filter: brightness(1.08); }
.linkbtn {
  background: none; border: 0; padding: 0.3rem 0.2rem; color: var(--ink-2);
  font-weight: 600; font-size: 0.9rem; text-decoration: underline; text-underline-offset: 3px;
}
.linkbtn:hover { color: var(--ink); }

/* ---------- Options dialog ---------- */
#options { width: min(32rem, calc(100% - 1.5rem)); }
.dlg.opts { grid-template-columns: minmax(0, 1fr); }
.dlg.opts h2 { margin: 0 0 1rem; font-size: 1.7rem; }
.opt-group { margin: 0 0 1.4rem; }
.opt-group h3 { margin: 0 0 0.4rem; color: var(--ink-2); font: 700 0.78rem var(--ff-body); text-transform: uppercase; letter-spacing: 0.08em; }
.opt { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.65rem 0; cursor: pointer; }
.opt-text { display: grid; gap: 0.1rem; min-width: 0; }
.opt-text strong { font-weight: 700; }
.opt-text small { color: var(--ink-2); font-size: 0.82rem; line-height: 1.3; }
/* sub-options: one tab to the right, with a guide line, like nested code */
.opt-sub { margin-left: 0.5rem; padding-left: 1.1rem; border-left: 2px solid var(--line); transition: opacity 0.2s; }
.opt-sub.is-off { opacity: 0.45; }
.opt-sub.is-off .opt { cursor: not-allowed; }
/* iOS-like switch: the knob slides, the track changes color */
.switch {
  appearance: none; -webkit-appearance: none; flex: none; position: relative; width: 2.9rem; height: 1.75rem; margin: 0;
  background: var(--line); border: 0; border-radius: 999px; cursor: pointer; transition: background-color 0.2s ease;
}
.switch::before {
  content: ""; position: absolute; top: 0.2rem; left: 0.2rem; width: 1.35rem; height: 1.35rem; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgb(0 0 0 / 0.35); transition: transform 0.2s ease;
}
.switch:checked { background: var(--accent); }
.switch:checked::before { transform: translateX(1.15rem); }
.switch:disabled { cursor: not-allowed; }
.switch:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .switch, .switch::before { transition: none; } }

/* ---------- Main area ---------- */
main { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }

.notice {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem;
  margin: 0 0 0.6rem; padding: 0.45rem 0.8rem;
  background: var(--surface); border: var(--bw) solid var(--line); border-left: 5px solid var(--accent);
  border-radius: var(--radius-s); font-size: 0.88rem;
}
.notice div > p { margin: 0; }
.notice div > p + p { margin-top: 0.25rem; }
.notice .linkbtn { flex: none; padding-block: 0; }
.loading { margin: auto; padding: 3rem 0; color: var(--ink-2); }

/* ---------- Calendar ---------- */
.cal-layout {
  flex: 1 1 auto; min-height: 0;
  display: grid; grid-template-columns: minmax(0, 1fr) clamp(16rem, 19vw, 19rem); gap: 0.75rem 1rem;
  padding-bottom: 0.5rem;
}
.cal { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.55rem; }
.cal-title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 1rem; min-width: 0; }
.cal-title h2 { font-size: clamp(1.45rem, 2.8vw, 2.1rem); }
.status { margin: 0; color: var(--ink-2); font-size: 0.9rem; }
.status .linkbtn { margin-left: 0.4rem; padding-block: 0; }
.cal-nav { display: flex; align-items: center; gap: 0.4rem; flex: none; }

.dow, .grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 0.25rem; }
.dow { margin-bottom: 0.3rem; color: var(--ink-2); font-size: 0.8rem; font-weight: 600; text-align: center; }
.grid {
  flex: 1 1 auto; min-height: 0;
  grid-template-rows: repeat(var(--rows, 6), minmax(0, 1fr));
}

.cell {
  position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 0.25rem;
  min-height: 0; min-width: 0; padding: 0 0.3rem 0.35rem; text-align: left; cursor: pointer;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: var(--radius-s);
  transition: background-color 0.15s;
}
.cell:hover { background: var(--surface-2); }
.cell.is-out { opacity: 0.45; }
.cell.is-selected { background: var(--surface-2); box-shadow: inset 0 0 0 2px var(--accent); }
[data-theme="anime"] .cell { box-shadow: 2px 2px 0 var(--hard); }
[data-theme="anime"] .cell.is-selected { box-shadow: inset 0 0 0 3px var(--accent), 2px 2px 0 var(--hard); }

.cell-head {
  /* the whole top strip of the cell is clickable: the day number plus some extra room around it */
  display: flex; align-items: center; flex: none; width: calc(100% + 0.6rem); margin-inline: -0.3rem;
  padding: 0.5rem 0.3rem 0.35rem; text-align: left;
  background: none; border: 0; border-radius: var(--radius-s) var(--radius-s) 0 0;
  transition: background-color 0.15s;
}
.cell-head:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.cell-head:focus-visible { outline-offset: -3px; }

.num {
  display: grid; place-items: center; align-self: flex-start; flex: none;
  min-width: 1.65rem; height: 1.65rem; padding: 0 0.3rem;
  border-radius: 999px; font: var(--w-display) 0.95rem / 1 var(--ff-display); font-stretch: var(--stretch);
  letter-spacing: 0; text-transform: none;
}
.is-today .num { background: var(--accent); color: var(--on-accent); }

.pills { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pill {
  --cat: var(--c-film);
  display: block; width: 100%; min-width: 0; padding: 0.1rem 0.3rem 0.1rem 0.45rem;
  border: 0; text-align: left; cursor: pointer;
  font-size: 0.74rem; line-height: 1.3; font-weight: 600; color: var(--ink);
  background: color-mix(in srgb, var(--cat) 17%, transparent);
  box-shadow: inset 3px 0 0 var(--cat); border-radius: 3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background-color 0.2s ease-out;
}
.pill[data-cat="tv"] { --cat: var(--c-tv); }
.pill[data-cat="anime"] { --cat: var(--c-anime); }
.pill:hover { background: color-mix(in srgb, var(--cat) 36%, transparent); }
.more {
  width: 100%; padding: 0 0 0 0.45rem; border: 0; background: none; text-align: left; cursor: pointer;
  font-size: 0.72rem; font-weight: 600; line-height: 1.3; color: var(--ink-2);
}
.more:hover { color: var(--ink); text-decoration: underline; }

.dots { display: none; flex-wrap: wrap; justify-content: center; gap: 3px; }
.dots i { --cat: var(--c-film); width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--cat); }
.dots i[data-cat="tv"] { --cat: var(--c-tv); }
.dots i[data-cat="anime"] { --cat: var(--c-anime); }

/* ---------- Sidebar: next release + selected day ---------- */
.side { display: flex; flex-direction: column; gap: 0.75rem; min-height: 0; min-width: 0; }

.hero {
  flex: none;
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.6rem 0.9rem; align-items: center;
  padding: 0.8rem; background: var(--hero-bg); border: var(--bw) solid var(--hero-line);
  border-radius: calc(var(--radius) * 1.2); box-shadow: var(--shadow);
}
.hero-poster {
  width: 4.4rem; aspect-ratio: 2 / 3; border-radius: var(--radius-s);
  overflow: hidden; border: var(--bw) solid var(--line); background: var(--surface-2); cursor: pointer;
}
.hero-text { min-width: 0; }
.hero-kicker { margin: 0 0 0.2rem; color: var(--ink-2); font-size: 0.82rem; font-weight: 600; }
[data-theme="anime"] .hero-kicker { color: var(--ink); }
.hero h2 { font-size: clamp(1.25rem, 1.8vw, 1.6rem); overflow-wrap: anywhere; }
.title-btn {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  width: 100%; padding: 0; background: none; border: 0; color: inherit; text-align: left;
  font: inherit; letter-spacing: inherit; text-transform: inherit; font-stretch: inherit;
}
.title-btn:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.hero-when { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.5rem; margin: 0.45rem 0 0; font-size: 0.88rem; font-weight: 500; }
.hero-cd { grid-column: 1 / -1; }
.today-note {
  margin: 0; font: var(--w-display) 1.4rem / 1.1 var(--ff-display); font-stretch: var(--stretch);
  text-transform: var(--tt); color: var(--accent);
}
[data-theme="anime"] .today-note { color: var(--ink); }

.cd { display: flex; gap: 0.4rem; }
.cd-u {
  flex: 1; min-width: 0; padding: 0.4rem 0.2rem 0.35rem; text-align: center;
  background: var(--surface-2); border: var(--bw) solid var(--line); border-radius: var(--radius-s);
}
[data-theme="anime"] .cd-u { background: var(--surface); box-shadow: 2px 2px 0 var(--hard); }
.cd-u b {
  display: block; font: var(--w-display) 1.5rem / 1 var(--ff-display);
  font-stretch: var(--stretch); letter-spacing: 0; font-variant-numeric: tabular-nums;
}
[data-theme="film"] .cd-u b, [data-theme="tv"] .cd-u b { color: var(--accent); }
.cd-u span { display: block; margin-top: 0.25rem; font-size: 0.72rem; color: var(--ink-2); }
.cd-u .short { display: none; }

/* Selected day */
.day {
  flex: 1 1 auto; min-height: 0; overflow: auto;
  padding: 1rem 1.5rem 1.25rem; /* side room lets hovered entries grow 15% without being clipped */
  background: var(--surface); border: var(--bw) solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.day-head h2 { font-size: 1.4rem; }
.rel { margin: 0.25rem 0 0; color: var(--ink-2); font-size: 0.9rem; }
.entries { display: grid; gap: 0.6rem; margin: 0.9rem 0 0; padding: 0; list-style: none; }
.day-empty { margin: 0.9rem 0 0; color: var(--ink-2); }
.day-empty .linkbtn { padding-left: 0; }

/* ---------- Entries (day panel) and cards (timeline): hover = scale 1.15 ---------- */
.entry {
  position: relative; z-index: 0;
  display: grid; grid-template-columns: 3.4rem minmax(0, 1fr); gap: 0.75rem; width: 100%; padding: 0.5rem;
  text-align: left; background: var(--surface-2); color: inherit;
  border: var(--bw) solid var(--line); border-radius: var(--radius-s);
  transition: transform 0.2s ease-out, box-shadow 0.2s ease-out, border-color 0.2s ease-out;
}
.entry .poster { transition: transform 0.2s ease-out; transform-origin: left center; }
.entry-body { min-width: 0; }
.entry-title { display: block; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.entry .badges { margin-bottom: 0.3rem; }

.entry-tags { display: flex; flex-wrap: nowrap; gap: 0.25rem; margin-top: 0.3rem; overflow: hidden; }
/* by default the genres read as quiet text, on hover they turn into highlighted tags */
.entry-tags .tag {
  padding-inline: 0; background: transparent; border-color: transparent; color: var(--ink-2);
  white-space: nowrap;
  transition: background-color 0.2s ease-out, color 0.2s ease-out, border-color 0.2s ease-out, padding 0.2s ease-out;
}
.entry-tags .tag:not(:last-child)::after { content: ","; }

.entry-item, .card-item { position: relative; z-index: 0; transition: transform 0.2s ease-out; }
.entry-item:has(.entry:focus-visible) { transform: scale(1.15); z-index: 10; }
.entry:focus-visible { box-shadow: var(--shadow); }
.entry:focus-visible .poster { transform: scale(1.12); }
.entry:focus-visible .entry-tags .tag,
.entry:hover .entry-tags .tag { padding-inline: 0.45rem; background: color-mix(in srgb, var(--cat) 22%, var(--surface)); border-color: var(--cat); color: var(--ink); }
.entry:focus-visible .entry-tags .tag::after,
.entry:hover .entry-tags .tag::after { content: none; }
.entry:focus-visible .entry-tags, .entry:hover .entry-tags { flex-wrap: wrap; overflow: visible; row-gap: 0.25rem; } /* the box grows downwards instead of clipping tags */
@media (hover: hover) {
  .entry-item:hover { transform: scale(1.15); z-index: 10; }
  .entry:hover { box-shadow: var(--shadow); border-color: var(--ink); }
  .entry:hover .poster { transform: scale(1.12); }
}
.entry[data-cat="film"] { --cat: var(--c-film); }
.entry[data-cat="tv"] { --cat: var(--c-tv); }
.entry[data-cat="anime"] { --cat: var(--c-anime); }

.tag {
  --cat: var(--c-film);
  display: inline-block; padding: 0.05rem 0.55rem; font-size: 0.74rem; font-weight: 600; line-height: 1.5;
  color: var(--ink); background: var(--surface-2); border: var(--bw) solid var(--line); border-radius: 999px;
}

/* ---------- Poster, badge ---------- */
.poster {
  --cat: var(--c-film);
  position: relative; display: block; aspect-ratio: 2 / 3; overflow: hidden;
  border-radius: var(--radius-s); background: var(--surface-2);
}
.poster[data-cat="tv"] { --cat: var(--c-tv); }
.poster[data-cat="anime"] { --cat: var(--c-anime); }
.poster img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.2s ease-out; }
.ph {
  display: grid; place-items: center; width: 100%; height: 100%;
  font: 800 1.9rem / 1 var(--ff-display); font-stretch: 100%; color: var(--ink); text-transform: none;
  background: linear-gradient(160deg, color-mix(in srgb, var(--cat) 38%, var(--surface)), var(--surface-2));
}
.badge {
  --cat: var(--c-film);
  display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.1rem 0.6rem 0.1rem 0.5rem;
  font-size: 0.76rem; font-weight: 700; line-height: 1.5; color: var(--ink);
  background: var(--surface); border: var(--bw) solid var(--line); border-radius: 999px;
}
.badge::before { content: ""; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--cat); }
.badge[data-cat="tv"] { --cat: var(--c-tv); }
.badge[data-cat="anime"] { --cat: var(--c-anime); }
.badges { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; vertical-align: middle; }
/* anime format tag ("TV" / "Movie"): same family as the Anime badge, filled so it reads as a sub-tag */
.badge-fmt { padding-inline: 0.55rem; background: color-mix(in srgb, var(--cat) 22%, var(--surface)); border-color: var(--cat); }
.badge-fmt::before { display: none; }

/* ---------- Timeline ---------- */
.tl { padding-bottom: 1rem; }
#tl-top { margin-bottom: 0.6rem; }
.tl .status { margin: 0.2rem 0 0.4rem; }
.tl-month { margin: 2.2rem 0 0.4rem; font-size: clamp(1.7rem, 3.6vw, 2.6rem); overflow-wrap: anywhere; }
#tl-list > .tl-month:first-child { margin-top: 0.6rem; }
[data-theme="film"] .tl-month { color: var(--accent); }
[data-theme="anime"] .tl-month {
  display: inline-block; padding: 0.25rem 0.9rem; background: var(--sticker); border: var(--bw) solid var(--line);
  border-radius: var(--radius-s); box-shadow: 3px 3px 0 var(--hard); transform: rotate(-1.2deg);
}
.tl-day {
  scroll-margin-top: calc(var(--header-h, 5rem) + 0.6rem);
  display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: 1rem 1.5rem;
  padding: 1.3rem 0; border-top: var(--bw) solid var(--line);
}
.tl-date { position: sticky; top: calc(var(--header-h, 5rem) + 0.8rem); align-self: start; display: grid; gap: 0.1rem; font-size: 1rem; }
.tl-date .wd { color: var(--ink-2); font: 600 0.95rem var(--ff-body); text-transform: none; letter-spacing: 0; font-stretch: 100%; }
.tl-date .dm { display: flex; align-items: baseline; gap: 0.4rem; }
.tl-date .dn { font-size: 3rem; line-height: 0.95; }
.tl-date .mo { color: var(--ink-2); font: 700 0.8rem var(--ff-body); text-transform: uppercase; letter-spacing: 0.08em; font-stretch: 100%; }
.tl-date .rel { margin: 0.2rem 0 0; font: 600 0.88rem var(--ff-body); text-transform: none; letter-spacing: 0; font-stretch: 100%; }
.tl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: 1.2rem 1.1rem; margin: 0; padding: 0; list-style: none; }

.card {
  position: relative; z-index: 0;
  display: flex; flex-direction: column; gap: 0.55rem; width: 100%; padding: 0;
  text-align: left; background: none; border: 0; color: inherit;
  transition: transform 0.2s ease-out;
}
.card .poster { border: var(--bw) solid var(--line); box-shadow: var(--shadow); transition: box-shadow 0.2s ease-out; }
.card .badges { position: absolute; left: 0.45rem; top: 0.45rem; right: 2.9rem; } /* leaves room for the heart */
.card-title { font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
/* genre tags slide up over the bottom of the poster on hover */
.poster-tags {
  position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-wrap: wrap; gap: 0.25rem;
  padding: 1.6rem 0.5rem 0.5rem;
  background: linear-gradient(to top, rgb(8 8 16 / 0.88), transparent);
  opacity: 0; transform: translateY(8px);
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}
.poster-tags .tag { background: rgb(255 255 255 / 0.16); border-color: rgb(255 255 255 / 0.4); color: #fff; }
.card-item:has(.card:focus-visible) { transform: scale(1.15); z-index: 10; }
.card:focus-visible .poster-tags { opacity: 1; transform: none; }
@media (hover: hover) {
  .card-item:hover { transform: scale(1.15); z-index: 10; }
  .card:hover .poster-tags { opacity: 1; transform: none; }
  .card:hover .poster img { transform: scale(1.06); }
  .card:hover .poster { box-shadow: 0 18px 32px -14px rgb(0 0 0 / 0.55); }
}

/* ---------- Hover preview for titles in the calendar cells ---------- */
.peek {
  --cat: var(--c-film);
  position: fixed; left: 0; top: 0; z-index: 60; width: 15.5rem; pointer-events: none;
  display: grid; grid-template-columns: 5.2rem minmax(0, 1fr); gap: 0.7rem; padding: 0.6rem;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: var(--radius); box-shadow: 0 20px 40px -16px rgb(0 0 0 / 0.5);
  opacity: 0; transform: scale(1); transform-origin: center;
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}
.peek.on { opacity: 1; transform: scale(1.15); }
.peek[data-cat="tv"] { --cat: var(--c-tv); }
.peek[data-cat="anime"] { --cat: var(--c-anime); }
.peek-body { min-width: 0; }
.peek-title { margin: 0.35rem 0 0.4rem; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.peek .tags { display: flex; flex-wrap: wrap; gap: 0.25rem; }
.peek .tag { background: color-mix(in srgb, var(--cat) 22%, var(--surface)); border-color: var(--cat); }

/* ---------- Dialogs ---------- */
dialog {
  width: min(46rem, calc(100% - 1.5rem)); max-height: calc(100dvh - 2rem); padding: 0; overflow: auto;
  background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: calc(var(--radius) * 1.4); box-shadow: var(--shadow);
}
dialog[open] { animation: pop 0.2s ease-out; }
dialog::backdrop { background: rgb(8 10 22 / 0.62); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
@keyframes pop { from { opacity: 0; transform: translateY(10px) scale(0.98); } }
.dlg { position: relative; display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 1.5rem; padding: 1.5rem; }
.dlg.about { grid-template-columns: minmax(0, 1fr); }
.dlg .close { position: absolute; right: 0.8rem; top: 0.8rem; }
.dlg-poster { align-self: start; }
.dlg-poster .poster { box-shadow: var(--shadow); border: var(--bw) solid var(--line); }
.dlg-body { min-width: 0; padding-right: 4.8rem; } /* room for the heart and the close button */
.dlg-body > p { margin: 0; }
.dlg h2 { margin: 0.7rem 0 0; font-size: clamp(1.7rem, 4vw, 2.5rem); overflow-wrap: anywhere; }
.dlg.about h2 { margin: 0 0 0.8rem; font-size: 1.7rem; }
.dlg.about p { margin: 0 0 0.7rem; max-width: 60ch; }
.orig { margin-top: 0.3rem !important; color: var(--ink-2); font-size: 0.95rem; }
.when { margin-top: 0.9rem !important; font-weight: 600; }
#d-cd { margin: 0.8rem 0 0; max-width: 22rem; }
#d-cd .rel { margin: 0; }
.dlg .tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 1rem; }
.dlg .tag { --cat: var(--c-film); }
.meta { display: grid; grid-template-columns: auto 1fr; gap: 0.25rem 1rem; margin: 0.9rem 0 0; font-size: 0.93rem; }
.meta dt { color: var(--ink-2); }
.meta dd { margin: 0; font-weight: 600; }
/* Synopsis: long text is clamped to ~6 lines and fades out at the bottom. On hover/focus the text
   brightens and "Read more" appears; on touch screens (no hover) the button is always visible. */
.syn { position: relative; margin-top: 1rem; max-width: 62ch; }
.syn-text { margin: 0; white-space: pre-line; transition: opacity 0.2s, -webkit-mask-image 0.2s; }
.syn.is-clamped:not(.is-open) .syn-text {
  max-height: 9em; overflow: hidden; opacity: 0.78;
  -webkit-mask-image: linear-gradient(#000 45%, transparent 100%); mask-image: linear-gradient(#000 45%, transparent 100%);
}
.syn.is-clamped:not(.is-open):hover .syn-text,
.syn.is-clamped:not(.is-open):focus-within .syn-text {
  opacity: 1;
  -webkit-mask-image: linear-gradient(#000 60%, rgb(0 0 0 / 0.4) 100%); mask-image: linear-gradient(#000 60%, rgb(0 0 0 / 0.4) 100%);
}
.syn-more {
  display: none; position: absolute; left: 50%; bottom: 0; transform: translate(-50%, 4px);
  padding: 0.3rem 1rem; font-size: 0.85rem; font-weight: 700;
  background: var(--accent); color: var(--on-accent); border: var(--bw) solid var(--accent); border-radius: 999px;
  opacity: 0; transition: opacity 0.2s, transform 0.2s;
}
.syn.is-clamped:not(.is-open) .syn-more { display: block; }
.syn.is-clamped:hover .syn-more, .syn.is-clamped .syn-more:focus-visible { opacity: 1; transform: translate(-50%, 0); }
@media (hover: none) { .syn.is-clamped:not(.is-open) .syn-more { opacity: 1; transform: translate(-50%, 0); } }
.note { margin-top: 0.5rem !important; color: var(--ink-2); font-size: 0.85rem; }
.dlg .btn { margin-top: 1.3rem; }

/* ---------- Footer ---------- */
.foot {
  flex: none; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.2rem 0 0.6rem; color: var(--ink-2); font-size: 0.8rem;
}
.foot .linkbtn { font-size: 0.8rem; padding-block: 0; }
.foot { min-height: 3rem; padding-inline-start: 3.4rem; } /* room for the day / night button, bottom left */
.foot { flex-wrap: wrap; row-gap: 0.2rem; } /* five links: on a narrow screen they go on a second line */

/* ---------- Day / night switch: fixed, bottom left (same setting as Options > Night mode) ---------- */
.mode-btn {
  position: fixed; z-index: 40; left: calc(env(safe-area-inset-left, 0px) + 0.75rem); bottom: calc(env(safe-area-inset-bottom, 0px) + 0.5rem);
  display: grid; place-items: center; width: 2.4rem; height: 2.4rem; padding: 0;
  background: var(--surface); color: var(--ink); border: var(--bw) solid var(--line); border-radius: 50%;
  box-shadow: var(--shadow); cursor: pointer;
  transition: transform 0.2s ease-out, background-color 0.2s;
}
.mode-btn:hover { transform: scale(1.08); background: var(--surface-2); }
.mode-btn svg { grid-area: 1 / 1; transition: opacity 0.25s ease, transform 0.35s ease; }
/* day shows the moon (tap = go dark), night shows the sun (tap = go light) */
.mode-btn .ico-sun { opacity: 0; transform: rotate(-70deg) scale(0.6); }
html[data-mode="night"] .mode-btn .ico-sun { opacity: 1; transform: none; }
html[data-mode="night"] .mode-btn .ico-moon { opacity: 0; transform: rotate(70deg) scale(0.6); }
html[data-mode="night"][data-theme="anime"] .mode-btn { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); background: color-mix(in srgb, var(--surface) 70%, transparent); }
html:not(.js) .mode-btn { display: none; }
/* the cookie bar covers this corner on phones: the button waits until it is answered */
body.view-timeline .foot { padding-block: 1.5rem 1.5rem; }

/* =========================================================
   Responsive
   ========================================================= */

/* Narrower than 60rem: one column. The calendar gets a guaranteed height (rows scale with the
   screen height), the hero strip and the day panel share the space that is left. */
@media (max-width: 59.99rem) {
  .cal-layout { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .grid { flex: none; grid-template-rows: repeat(var(--rows, 6), clamp(3.4rem, 9dvh, 8rem)); }
  .notice p { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

  /* hero becomes a slim strip */
  .hero { grid-template-columns: minmax(0, 1fr) auto; padding: 0.5rem 0.8rem; gap: 0.1rem 0.75rem; }
  .hero-poster, .hero-kicker { display: none; }
  .hero h2 { font-size: 1.1rem; }
  .title-btn { -webkit-line-clamp: 1; }
  .hero-when { flex-wrap: nowrap; margin-top: 0.2rem; font-size: 0.82rem; }
  .hero-when .badges { display: none; }
  .when-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .hero-cd { grid-row: 1 / span 2; grid-column: 2; }
  .cd { gap: 0.45rem; }
  .cd-u { flex: none; display: flex; align-items: baseline; gap: 1px; padding: 0; background: none; border: 0; box-shadow: none !important; }
  .cd-u b { font-size: 1.15rem; }
  .cd-u span { margin: 0; }
  .cd-u .full { display: none; }
  .cd-u .short { display: inline; font-size: 0.75rem; }
  .today-note { font-size: 1.05rem; }
  .day { padding: 0.8rem 1.25rem 1rem; }
  .day-head h2 { font-size: 1.2rem; }
}

/* Header: controls move to their own row */
@media (max-width: 62rem) {
  .top { grid-template-columns: minmax(0, 1fr) auto; }
  .brand { grid-column: 1; grid-row: 1; }
  .top-actions { grid-column: 2; grid-row: 1; }
  .controls { grid-column: 1 / -1; grid-row: 2; justify-content: flex-start; }
}

/* Phones: compact cells show colored dots instead of titles */
@media (max-width: 45rem) {
  .dow, .grid { gap: 0.22rem; }
  .cell { min-height: 2.2rem; align-items: center; padding: 0 0.1rem 0.25rem; gap: 0.15rem; }
  .cell-head { justify-content: center; width: 100%; margin-inline: 0; padding: 0.3rem 0 0.1rem; }
  .num { align-self: center; min-width: 1.5rem; height: 1.5rem; font-size: 0.88rem; }
  .pills { display: none; }
  .dots { display: flex; }
  .cal-title h2 { font-size: 1.35rem; }
}

@media (max-width: 30rem) {
  .top { gap: 0.5rem; padding-block: 0.6rem 0.5rem; }
  .brand { gap: 0.4rem; font-size: 1rem; }
  .top-actions { gap: 0.35rem; }
  .saved-btn { width: 2.2rem; height: 2.2rem; }
  .logo { gap: 3px; }
  .logo { --d: 0.5rem; }
  .seg { padding: 0.15rem; gap: 0; }
  .seg::before { top: 0.15rem; bottom: 0.15rem; left: 0.15rem; width: calc((100% - 0.3rem) / 2); }
  html[data-view="timeline"] .seg::before { transform: translateX(100%); }
  .seg button { padding: 0.3rem 0.45rem; font-size: 0.78rem; }
  .chips { gap: 0.35rem; }
  .chip { gap: 0.35rem; padding: 0.38rem 0.6rem 0.38rem 0.5rem; font-size: 0.84rem; }
  .chip .sw { width: 0.64rem; height: 0.64rem; }
  .chip .n { display: none; }
  /* The chips fill the row up to the search icon, so "Show all" wraps under them inside the group
     and the icon stays on the right of the last chip (as when all categories are on). */
  .chips { flex: 1 1 0; min-width: 0; }
  .chips #all { order: 1; }
  .search { align-self: flex-start; }
  /* search collapses into an icon and expands over the category chips while focused */
  .search { flex: 0 0 2.2rem; max-width: 2.2rem; margin-left: auto; }
  .search input { height: 2.2rem; padding: 0; color: transparent; caret-color: transparent; cursor: pointer; }
  .search input::placeholder { color: transparent; }
  .search > svg { left: 50%; transform: translate(-50%, -50%); }
  .search:focus-within { position: absolute; left: 0; right: 0; top: 0; z-index: 5; max-width: none; }
  /* results: edge to edge, as tall as the room above the keyboard (--sug-max from positionSuggest) */
  .sug { left: calc(-1 * var(--gutter)); right: calc(-1 * var(--gutter)); width: auto; max-width: none; max-height: var(--sug-max, 70dvh); border-radius: 0 0 var(--radius) var(--radius); }
  .sug-main { padding-block: 0.7rem; }
  .sug-go { height: 2.75rem; padding-inline: 1.1rem; }
  .search:focus-within input { padding: 0 0.9rem 0 2.5rem; color: var(--ink); caret-color: auto; cursor: text; }
  .search:focus-within input::placeholder { color: var(--ink-2); }
  .search:focus-within > svg { left: 0.85rem; transform: translateY(-50%); }
  .search.has-value input { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
  .status { display: none; } /* the month title is enough on phones */
}

/* Timeline on narrower screens */
@media (max-width: 40rem) {
  .tl-day { grid-template-columns: 1fr; gap: 0.8rem; }
  .tl-date { position: static; display: flex; align-items: baseline; gap: 0.6rem; }
  .tl-date .dn { font-size: 2rem; }
  .tl-date .mo { font-size: 0.72rem; }
  .tl-grid { grid-template-columns: repeat(auto-fill, minmax(8.2rem, 1fr)); }
  .dlg { grid-template-columns: 1fr; padding: 1.1rem; gap: 1rem; }
  .dlg-poster { max-width: 8.5rem; }
  .dlg-body { padding-right: 0; }
}

/* In the timeline the hero can be wide */
@media (min-width: 62rem) {
  .tl .hero { grid-template-columns: auto minmax(0, 1fr) auto; gap: 1rem 1.5rem; padding: 1rem 1.25rem; }
  .tl .hero-poster { width: 5.4rem; }
  .tl .hero h2 { font-size: clamp(1.6rem, 3vw, 2.4rem); }
  .tl .hero-cd { grid-column: auto; }
  .tl .cd-u { padding: 0.5rem 0.4rem 0.45rem; min-width: 4.2rem; }
  .tl .cd-u b { font-size: 1.9rem; }
}

/* Very short screens (landscape phones): let the page scroll instead of squeezing */
@media (max-height: 34rem) {
  body.view-calendar { height: auto; min-height: 100dvh; overflow: visible; }
  .cal-layout { flex: none; }
  .grid { grid-template-rows: repeat(var(--rows, 6), 4.4rem); }
  .day { max-height: 20rem; }
}

/* ---------- Reduced motion ---------- */
/* ---------- Trailer drawer: slides out of the dialog's right side like a keyboard tray ---------- */
#detail { --tray-w: clamp(22rem, calc(100vw - 49rem), 40rem); --handle-w: 2.5rem; overflow: visible; max-height: none; transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); }
#detail .dlg { background: var(--surface); border-radius: inherit; max-height: calc(100dvh - 2rem); overflow: auto; }
#detail.tray-open { transform: translateX(calc(var(--tray-w) / -2)); } /* keeps dialog + drawer centred on screen */
.tray {
  position: absolute; z-index: -1; /* behind .dlg: closed, only the handle sticks out */ top: 1.5rem; bottom: 1.5rem; min-height: 18rem; max-height: 33rem; left: 100%; width: var(--tray-w); /* same gap below as above */
  display: flex; transform: translateX(calc(-100% + var(--handle-w))); transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
.tray.is-open { transform: none; }
.tray-body {
  flex: 1; min-width: 0; display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 0.6rem; padding: 0.7rem; visibility: hidden; transition: visibility 0s 0.35s;
  background: var(--surface); border: var(--bw) solid var(--line); border-right: 0; border-radius: var(--radius) 0 0 var(--radius);
}
.tray.is-open .tray-body { visibility: visible; transition-delay: 0s; }
.tray-handle {
  flex: none; width: var(--handle-w); display: flex; align-items: center; justify-content: center; gap: 0.4rem; padding: 1rem 0;
  writing-mode: vertical-rl; font-weight: 700; letter-spacing: 0.04em;
  background: var(--accent); color: var(--on-accent); border: var(--bw) solid var(--accent); border-radius: 0 var(--radius) var(--radius) 0;
}
.tray-bar { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.tray-stage { min-height: 0; display: grid; place-items: center; overflow: hidden; background: #0b0b12; border-radius: var(--radius-s); }
.tray-stage iframe { width: 100%; height: 100%; border: 0; }
.gate { display: grid; gap: 0.55rem; justify-items: center; padding: 0.8rem; color: #ececf4; text-align: center; font-size: 0.82rem; line-height: 1.35; }
.gate p { margin: 0; }
.gate-remember { display: inline-flex; align-items: center; gap: 0.4rem; color: #b9b9c9; }
.switch { position: relative; display: inline-flex; align-items: center; gap: 0.4rem; color: var(--ink-2); font-size: 0.8rem; font-weight: 600; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch-ui { position: relative; width: 1.9rem; height: 1.05rem; border-radius: 999px; background: var(--line); transition: background-color 0.2s; }
.switch-ui::after { content: ""; position: absolute; top: 0.15rem; left: 0.15rem; width: 0.75rem; height: 0.75rem; border-radius: 50%; background: var(--surface); transition: transform 0.2s; }
.switch input:checked + .switch-ui { background: var(--accent); }
.switch input:checked + .switch-ui::after { transform: translateX(0.85rem); }
.switch input:focus-visible + .switch-ui { outline: 2px solid var(--ink); outline-offset: 2px; }

/* not enough room beside the dialog: the drawer opens below the page instead */
@media (max-width: 72rem) {
  #detail { overflow: auto; max-height: calc(100dvh - 2rem); }
  #detail .dlg { max-height: none; overflow: visible; }
  #detail.tray-open { transform: none; }
  .tray { position: static; z-index: auto; min-height: 0; max-height: none; width: auto; flex-direction: column-reverse; transform: none; border-top: var(--bw) solid var(--line); }
  .tray-handle { writing-mode: horizontal-tb; width: 100%; padding: 0.7rem; border-radius: 0; }
  .tray-handle svg { transform: none; }
  .tray-stage { aspect-ratio: 16 / 9; }
  .tray-body { display: none; grid-template-rows: none; border: 0; border-radius: 0; visibility: visible; }
  .tray.is-open .tray-body { display: grid; }
}

/* ---------- Heart: save a title ---------- */
.heart {
  display: inline-grid; place-items: center; flex: none; width: 2.1rem; height: 2.1rem; padding: 0;
  background: #fff; color: #1b1b24; border: 1px solid rgb(0 0 0 / 0.14); border-radius: 50%;
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.3); transition: transform 0.15s ease-out;
}
.heart svg { fill: none; stroke: currentColor; transition: fill 0.15s, stroke 0.15s; }
.heart:hover { transform: scale(1.1); }
.heart:active { transform: scale(0.92); }
.heart[aria-pressed="true"] svg { fill: #e5233d; stroke: #e5233d; animation: heart-pop 0.3s ease-out; }
.heart.sm { width: 1.9rem; height: 1.9rem; box-shadow: none; border-color: var(--line); }
.heart.sm svg { width: 16px; height: 16px; }
@keyframes heart-pop { 40% { transform: scale(1.3); } }
.entry-item .heart, .card-item .heart { position: absolute; z-index: 2; top: 0.45rem; right: 0.45rem; }
.entry-item .entry-body { padding-right: 1.8rem; }
.dlg .dlg-heart { position: absolute; right: 3.6rem; top: 0.8rem; width: 2.3rem; height: 2.3rem; }
.sug-row { grid-template-columns: minmax(0, 1fr) auto auto; }

/* ---------- Alerts for saved titles ---------- */
.toasts {
  position: fixed; z-index: 90; left: 50%; transform: translateX(-50%); bottom: calc(env(safe-area-inset-bottom, 0px) + 1rem);
  display: grid; gap: 0.5rem; width: min(30rem, calc(100% - 1.5rem)); pointer-events: none;
}
.toast {
  pointer-events: auto; display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 0.7rem;
  padding: 0.7rem 0.8rem; background: var(--surface); color: var(--ink);
  border: var(--bw) solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); animation: pop 0.25s ease-out;
}
.toast-ico { display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%; background: #e5233d; color: #fff; }
.toast-ico svg { fill: currentColor; stroke: currentColor; }
.toast-text { display: grid; min-width: 0; font-size: 0.92rem; line-height: 1.3; overflow-wrap: anywhere; }
.toast-text strong { font-weight: 700; }
.toast-open { padding: 0.35rem 0.8rem; font-weight: 700; font-size: 0.85rem; background: var(--accent); color: var(--on-accent); border: var(--bw) solid var(--accent); border-radius: 999px; }
.toast-ask { grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; }
.toast-ask .toast-ico { background: var(--accent); color: var(--on-accent); font-weight: 800; }
.toast-actions { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.toast-alt { background: none; color: var(--ink); border-color: var(--line); }
.toast-x { width: 1.8rem; height: 1.8rem; padding: 0; background: none; border: 0; color: var(--ink-2); font-size: 1.3rem; line-height: 1; }

/* ---------- Saved titles sheet: a horizontal timeline ---------- */
#saved { width: min(calc(100% - 1.5rem), 84rem); max-width: none; margin: 4.2rem auto auto; max-height: calc(100dvh - 5rem); }
.sv { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.9rem; padding: 1.2rem 0 1.2rem 1.4rem; } /* minmax(0, ...): a long timeline scrolls inside .sv-scroll, never the dialog */
.sv-head { display: flex; align-items: center; gap: 0.8rem; padding-right: 1.2rem; }
.sv-head h2 { margin: 0; font-size: 1.5rem; }
.sv-sub { margin: 0 auto 0 0; color: var(--ink-2); font-weight: 600; }
.sv-alerts { margin: 0; padding: 0 1.4rem 0 0; list-style: none; display: grid; gap: 0.4rem; }
.sv-alert { padding: 0.55rem 0.8rem; background: var(--surface-2); border: var(--bw) solid var(--line); border-radius: var(--radius-s); line-height: 1.35; }
.sv-new { margin-right: 0.5rem; padding: 0.05rem 0.45rem; background: #e5233d; color: #fff; border-radius: 999px; font: 700 0.7rem var(--ff-body); text-transform: uppercase; letter-spacing: 0.05em; }
.sv-empty { margin: 0; padding: 1.5rem 1.4rem 1.5rem 0; color: var(--ink-2); max-width: 46ch; }
.sv-scroll { overflow-x: auto; overflow-y: hidden; padding-bottom: 0.5rem; scroll-snap-type: x proximity; overscroll-behavior-x: contain; }
.sv-scroll { cursor: grab; }
.sv-scroll.is-dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; -webkit-user-select: none; }
.sv-scroll.is-dragging * { pointer-events: none; }
.sv-track { display: flex; align-items: flex-start; margin: 0; padding: 0 1.4rem 0 0; list-style: none; width: max-content; min-width: 100%; }
.sv-col { flex: none; width: 15.5rem; padding: 0 0.5rem; scroll-snap-align: start; }
.sv-when { display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; column-gap: 0.55rem; align-items: end; height: 3.4rem; padding-left: 0.3rem; }
.sv-day { grid-row: 1 / 3; align-self: center; font: 800 2.2rem/1 var(--ff-display, var(--ff-body)); }
.sv-mon { align-self: end; color: var(--ink-2); font: 700 0.8rem var(--ff-body); letter-spacing: 0.08em; }
.sv-rel { align-self: start; font: 600 0.85rem var(--ff-body); }
.sv-rail { position: relative; height: 1.2rem; }
.sv-rail::before { content: ""; position: absolute; left: -0.5rem; right: -0.5rem; top: 50%; height: 2px; background: var(--line); transform: translateY(-50%); }
.sv-dot { position: absolute; left: 0.3rem; top: 50%; width: 0.8rem; height: 0.8rem; border-radius: 50%; background: var(--accent); border: 2px solid var(--surface); transform: translateY(-50%); box-shadow: 0 0 0 2px var(--accent); }
.is-today .sv-dot { background: #e5233d; box-shadow: 0 0 0 2px #e5233d, 0 0 0 6px color-mix(in srgb, #e5233d 30%, transparent); }
.is-past { opacity: 0.62; }
.is-past .sv-dot { background: var(--ink-2); box-shadow: 0 0 0 2px var(--ink-2); }
.sv-cards { display: grid; gap: 0.6rem; margin: 0.6rem 0 0; padding: 0; list-style: none; }
.sv-card { display: grid; gap: 0.5rem; padding: 0.5rem; background: var(--surface-2); border: var(--bw) solid var(--line); border-radius: var(--radius-s); }
.sv-open { display: grid; grid-template-columns: 3.4rem minmax(0, 1fr); gap: 0.7rem; align-items: start; padding: 0; background: none; border: 0; color: inherit; text-align: left; }
.sv-info { display: grid; gap: 0.3rem; min-width: 0; }
.sv-title { font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.sv-actions { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.sv-go { padding: 0.3rem 0.9rem; font-weight: 700; font-size: 0.82rem; background: var(--accent); color: var(--on-accent); border: var(--bw) solid var(--accent); border-radius: 999px; }
@media (max-width: 30rem) {
  .sv { padding-left: 1rem; }
  .sv-col { width: 13.5rem; }
  .heart { width: 2.4rem; height: 2.4rem; }
  .sv-go { padding-block: 0.5rem; }
  .toast { grid-template-columns: auto minmax(0, 1fr) auto; }
  .toast-x { display: none; }
}

/* very narrow phones: the three-dot logo makes way so the name, the view switch and the heart all fit */
@media (max-width: 25rem) {
  .logo { display: none; }
}

/* ---------- Year overview: 12 months with a heatmap of releases per day ---------- */
.year-btn { display: inline-flex; align-items: center; gap: 0.4rem; }
.year-btn svg { flex: none; }

#year {
  /* one color per category for the heat spots. In the single-category themes --c-film/--c-tv/--c-anime
     are all the same accent, so (like the search dropdown) the dialog brings its own distinct set. */
  --h-film: var(--c-film); --h-tv: var(--c-tv); --h-anime: var(--c-anime);
  width: min(70rem, calc(100% - 1.5rem));
}
[data-theme="film"] #year, [data-theme="tv"] #year { --h-film: #ff7a45; --h-tv: #5b9bff; --h-anime: #ff5fa6; }
[data-theme="anime"] #year { --h-film: #d9480f; --h-tv: #2e6be6; --h-anime: #d62a7e; }
#year .chip { --cat: var(--h-film); }
#year .chip[data-cat="tv"] { --cat: var(--h-tv); }
#year .chip[data-cat="anime"] { --cat: var(--h-anime); }

.yr { display: grid; gap: 0.9rem; padding: 0 1.4rem 1.2rem; }
.yr-head {
  position: sticky; top: 0; z-index: 3; display: flex; align-items: center; justify-content: space-between; gap: 0.8rem;
  margin-inline: -1.4rem; padding: 1rem 1.4rem 0.6rem; background: var(--surface);
}
.yr-nav { display: flex; align-items: center; gap: 0.5rem; }
.yr-nav .icon-btn { border: var(--bw) solid var(--line); border-radius: 999px; background: var(--surface-2); }
.yr-nav .icon-btn:hover:not(:disabled) { border-color: var(--accent); }
.yr-nav .btn-s { white-space: nowrap; }
.yr-nav h2 { margin: 0 0.4rem; min-width: 4.2ch; text-align: center; font-size: 1.7rem; font-variant-numeric: tabular-nums; }
.yr-filters { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }

.yr-months { display: grid; grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr)); gap: 0.8rem; }
.ym {
  display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; gap: 0.35rem; align-content: start; padding: 0.55rem 0.6rem 0.65rem;
  background: var(--surface-2); border: var(--bw) solid var(--line); border-radius: var(--radius);
}
.ym.is-now { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ym.is-view { border: 2px dashed var(--ink-2); } /* the month open in the calendar, besides the current one */
.ym.is-off { opacity: 0.45; }
.ym-name {
  display: flex; align-items: center; gap: 0.35rem; width: 100%; min-width: 0; padding: 0.15rem 0.2rem; text-align: left;
  background: none; color: var(--ink); border: 0; border-radius: var(--radius-s);
  font: var(--w-display, 700) 1.02rem/1.2 var(--ff-display, inherit); font-stretch: var(--stretch, 100%);
}
.ym-name:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.ym-name:disabled { cursor: default; }
.ym-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ym-now {
  flex: none; padding: 0.05rem 0.4rem; background: var(--accent); color: var(--on-accent); border-radius: 999px;
  font: 700 0.66rem/1.5 var(--ff-body, inherit); text-transform: uppercase; letter-spacing: 0.06em;
}
.ym-count { flex: none; color: var(--ink-2); font: 600 0.8rem var(--ff-body, inherit); font-variant-numeric: tabular-nums; }

.ym-dow, .ym-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.ym-dow { position: relative; z-index: 1; } /* weekday letters stay above the heat */
.ym-dow span { text-align: center; color: var(--ink-2); font-size: 0.66rem; font-weight: 700; }
.yd {
  position: relative; display: grid; place-items: center; height: var(--yd-h, 1.75rem); min-width: 0; padding: 0; /* fixed height: aspect-ratio on 400 cells made layout twice as slow */
  background: none; border: 0; border-radius: 50%; color: var(--ink); font: inherit;
}
button.yd { cursor: pointer; }
/* heat map: a canvas behind the numbers (drawn by paintHeat in app.js). Blobs of consecutive days
   merge into one soft shape; it extends a little past the grid so edge days are not cut. */
.ym-days { position: relative; }
.heat { position: absolute; z-index: 0; pointer-events: none; }
.yd.has:hover .yd-num { background: color-mix(in srgb, var(--ink) 14%, transparent); }
.yd-num {
  position: relative; z-index: 1; display: grid; place-items: center; width: 1.45em; height: 1.45em; border-radius: 50%;
  font-size: 0.68rem; font-weight: 600; font-variant-numeric: tabular-nums;
  text-shadow: 0 0 3px var(--surface-2), 0 0 3px var(--surface-2), 0 0 6px var(--surface-2); /* stays readable on a spot */
}
.yd.has .yd-num { font-weight: 800; }
.yd.is-today .yd-num { background: var(--accent); color: var(--on-accent); text-shadow: none; font-weight: 800; }
button.yd:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

.yr-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; margin: 0; color: var(--ink-2); font-size: 0.82rem; }
.yr-ramp { width: 5.5rem; height: 0.6rem; border-radius: 999px; background: linear-gradient(90deg, color-mix(in srgb, var(--ink) 10%, transparent), var(--ink-2)); }
.yr-legend-note { margin-left: auto; }

/* tooltip: a single fixed element inside the dialog (only there can it sit above it) */
.yr-tip {
  position: fixed; left: 0; top: 0; z-index: 10; min-width: 8.5rem; padding: 0.5rem 0.7rem; pointer-events: none;
  background: var(--surface); color: var(--ink); border: var(--bw) solid var(--line); border-radius: var(--radius-s);
  box-shadow: 0 12px 28px -12px rgb(0 0 0 / 0.55);
  opacity: 0; transition: opacity 0.12s ease-out; will-change: transform; contain: layout paint;
}
.yr-tip.on { opacity: 1; } /* position is set per frame by JS: no transform transition, or the label trails the cursor */
.yt-date { margin: 0 0 0.3rem; font-weight: 800; font-size: 0.95rem; }
.yt-list { display: grid; gap: 0.2rem; margin: 0; padding: 0; list-style: none; }
.yt-list li { display: flex; align-items: center; gap: 0.45rem; font-size: 0.88rem; }
.yt-list li span { flex: 1 1 auto; }
.yt-list b { font-variant-numeric: tabular-nums; }
.yt-sw { width: 0.7rem; height: 0.7rem; border-radius: 50%; background: var(--h-film); }
.yt-list li[data-cat="tv"] .yt-sw { background: var(--h-tv); }
.yt-list li[data-cat="anime"] .yt-sw { background: var(--h-anime); }
.yt-total { margin: 0.35rem 0 0; padding-top: 0.3rem; border-top: 1px solid var(--line); color: var(--ink-2); font-size: 0.8rem; font-weight: 600; }

@media (max-width: 45rem) {
  .year-btn { width: 2.3rem; padding: 0; justify-content: center; }
  .year-btn span { display: none; }
  .yr { padding-inline: 0.9rem; }
  .yr-head { margin-inline: -0.9rem; padding-inline: 0.9rem; }
  .yr-nav { gap: 0.35rem; }
  .yr-nav h2 { margin-inline: 0.15rem; font-size: 1.4rem; }
  .yr-nav .btn-s { padding-inline: 0.75rem; font-size: 0.82rem; }
  .yr-legend-note { margin-left: 0; flex-basis: 100%; }
}
@media (max-width: 30rem) {
  .yr-months { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; }
  .ym { padding-inline: 0.4rem; }
  .ym-count { display: none; }
  .ym-days { --yd-h: 1.5rem; }
  .yd-num { font-size: 0.6rem; }
  #year .chip .n { display: inline; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .entry-item:hover, .entry-item:has(:focus-visible), .card-item:hover, .card-item:has(:focus-visible), .peek.on { transform: none !important; }
  .entry:hover .poster, .card:hover .poster img { transform: none !important; }
}

/* Plain list of a month's titles, written into the HTML of the month pages for search engines.
   Without JavaScript it is simply readable; with JavaScript it stays hidden and app.js removes it. */
.seo-releases { max-width: 46rem; margin: 2rem auto; padding: 0 1rem; }
.seo-releases ul { padding-left: 1.2rem; }
.js .seo-releases { display: none; }

/* "WonderCalendar" is longer than the old name: a slightly smaller wordmark on phones keeps it whole
   (as whole as the old one was, from 375 px up). */
@media (max-width: 30rem) {
  .brand { gap: 0.3rem; font-size: 0.75rem; }
  .logo { gap: 2px; }
  .logo { --d: 0.38rem; }
  .brand-text { letter-spacing: 0; line-height: 1.05; overflow: visible; }
  /* "Wonder" and, below it, "Calendar" (phones only) */
  .brand-text .holo { display: block; }
}

/* Phones: the page scrolls instead of squeezing everything above the ad and footer. The titles of the
   selected day come right below the calendar (app.js scrolls them into view on a tap), and the
   Next release strip follows them. */
@media (max-width: 45rem) {
  body.view-calendar { height: auto; min-height: 100dvh; overflow: visible; }
  .cal-layout { flex: none; }
  .day { order: 1; flex: none; max-height: none; overflow: visible; scroll-margin-top: 0.75rem; }
  .hero { order: 2; }

  /* Next release: no longer a slim strip. Title and date may wrap over several lines and the box grows
     with them (the page scrolls anyway). The poster sits on the right, the genre badges stay hidden, the countdown goes below the text. */
  .hero { grid-template-columns: minmax(0, 1fr) auto; padding: 0.8rem 1rem 0.9rem; gap: 0.5rem 0.9rem; align-items: start; }
  .hero-kicker { display: block; }
  .hero-text { grid-column: 1; grid-row: 1; }
  .hero-cd { grid-column: 1; grid-row: 2; }
  .hero-poster { display: block; grid-column: 2; grid-row: 1 / span 2; align-self: start; width: 5.2rem; }
  .title-btn { display: block; -webkit-line-clamp: unset; overflow: visible; overflow-wrap: anywhere; }
  .hero h2 { font-size: 1.25rem; line-height: 1.15; }
  .hero-when { flex-wrap: wrap; margin-top: 0.4rem; font-size: 0.9rem; }
  .when-text { overflow: visible; text-overflow: clip; white-space: normal; }
}

/* Phones, Anime theme: the frosted glass (backdrop-filter) on every day cell and on the Next release box, and the
   saturate() filter on the balls, are re-painted on every scroll frame (about 40 blurred panels), which makes
   mid-range phones stutter. Only the day panel (the titles of the selected day) keeps the glass: it is one
   element. Cells and Next release are simply more opaque, the balls are plain. */
@media (max-width: 45rem) {
  html[data-mode="night"][data-theme="anime"] :is(.cell, .hero, .mode-btn) {
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  html[data-mode="night"][data-theme="anime"] .cell { background: color-mix(in srgb, var(--surface) 88%, transparent); }
  html[data-mode="night"][data-theme="anime"] .cell:is(:hover, .is-selected) { background: color-mix(in srgb, var(--surface-2) 90%, transparent); }
  html[data-mode="night"][data-theme="anime"] .hero { --hero-bg: linear-gradient(135deg, rgb(110 76 164 / 0.94), rgb(84 58 138 / 0.92)); }
  html[data-mode="night"] .deco-anime .ball { filter: none; opacity: 0.22; }
}

/* ---------- Phone: arrows + swipe between days with releases ---------- */
.day-nav { display: none; }
.day-title { min-width: 0; }
@media (max-width: 45rem) {
  .day { touch-action: pan-y; }
  .day-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 0.5rem; }
  .day-title { text-align: center; }
  .day-nav {
    display: inline-grid; place-items: center; width: 2.4rem; height: 2.4rem; padding: 0;
    background: var(--surface-2); color: var(--ink); border: var(--bw) solid var(--line); border-radius: 50%;
  }
  .day-nav:disabled { opacity: 0.3; }
  .day-nav:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  .day.slide-next { animation: day-in-next 0.22s ease-out; }
  .day.slide-prev { animation: day-in-prev 0.22s ease-out; }
}
@keyframes day-in-next { from { opacity: 0; transform: translateX(28px); } }
@keyframes day-in-prev { from { opacity: 0; transform: translateX(-28px); } }
@media (prefers-reduced-motion: reduce) { .day.slide-next, .day.slide-prev { animation: none; } }

/* ---------- Hover bubble: heart for saved titles ---------- */
/* The bubble keeps its usual size; with a heart it is only slightly wider on the right, and the heart sits in that extra strip */
.peek { --heart-room: 1.6rem; }
.peek:has(.peek-heart) { width: calc(15.5rem + var(--heart-room)); padding-right: calc(0.6rem + var(--heart-room)); }
.peek-heart { position: absolute; top: 0.6rem; right: 0.6rem; display: grid; place-items: center; }
.peek-heart svg { width: 18px; height: 18px; fill: #e5233d; stroke: #e5233d; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- Year overview: days with a saved title get a heart instead of the dot ----------
   Colors come from the active theme (--accent is light in night mode, dark in day mode; --on-accent is the
   number on top of it). The mask is cropped to the heart's own bounding box (viewBox 2 3 20 18), so the
   shape fills the box exactly and the number sits in its middle (nudged up a hair: the heart is heavier on top). */
.yd.is-saved .yd-num {
  position: relative; box-sizing: border-box; width: 2.1em; height: 1.9em; padding-bottom: 0.14em;
  background: none; color: var(--on-accent); text-shadow: none; font-weight: 800;
}
.yd.is-saved .yd-num::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='2 3 20 18'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='2 3 20 18'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}
.yd.is-saved:hover .yd-num, .yd.is-saved.is-today .yd-num { background: none; }
@media (max-width: 30rem) { .yd.is-saved .yd-num { width: 2.2em; height: 2em; } }

/* Popular titles: small flame next to the title */
.flame { display: inline-block; flex: none; width: 0.95em; height: 0.95em; margin-left: 0.3em; vertical-align: -0.12em; color: var(--pop-fl); }
.flame svg { display: block; width: 100%; height: 100%; fill: currentColor; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; transform-origin: 50% 100%; }
.pill .flame { width: 0.85em; height: 0.85em; margin: 0 0.25em 0 0; vertical-align: -0.1em; }

/* ---------- "Popular": always orange, readable on every theme and mode ----------
   Day: dark orange-brown text on a pale orange tint, strong orange outline. Night: light orange text on a
   deep orange tint. The tint is mixed with the surface the pill sits on (--surface-2, the entry background),
   so the contrast holds on all six theme/mode combinations (text >= 5.4:1, outline and flame >= 3.4:1). */
:root { --pop-ink: #8a3700; --pop-bd: #d9480f; --pop-fl: #d9480f; --pop-mix: 16%; --pop-spark: #e8590c; --pop-medal: #ff7a1a; --pop-medal-ink: #3a1500; }
html[data-mode="night"] { --pop-ink: #ffb27a; --pop-bd: #ff7a1a; --pop-fl: #ff8a2a; --pop-mix: 20%; --pop-spark: #ffb27a; }
.pop-row { display: block; margin-top: 0.3rem; }
.pop-pill {
  display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.05rem 0.6rem 0.05rem 0.45rem;
  font: 700 0.75rem/1.5 var(--ff-body); color: var(--pop-ink);
  background: color-mix(in srgb, #ff7a1a var(--pop-mix), var(--surface-2));
  border: 1px solid var(--pop-bd); border-radius: 999px;
}
.pop-fl { position: relative; display: inline-block; flex: none; width: 0.95rem; height: 0.95rem; color: var(--pop-fl); }
.pop-fl svg { display: block; width: 100%; height: 100%; fill: currentColor; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; transform-origin: 50% 100%; }
.pop-fl i { position: absolute; left: 50%; bottom: 55%; width: 3px; height: 3px; margin-left: -1.5px; border-radius: 50%; background: var(--pop-spark); opacity: 0; }
.pop-fl i:nth-of-type(2) { margin-left: -5px; }
.pop-fl i:nth-of-type(3) { margin-left: 2px; }

/* detail sheet: medal on the poster corner */
.dlg-poster { position: relative; }
.poster-medal {
  position: absolute; z-index: 2; left: -0.5rem; top: -0.5rem; display: grid; place-items: center; width: 2rem; height: 2rem;
  background: var(--pop-medal); color: var(--pop-medal-ink); border: 2px solid var(--surface); border-radius: 50%;
}
.poster-medal svg { width: 1.1rem; height: 1.1rem; fill: currentColor; stroke: currentColor; stroke-width: 1.2; stroke-linejoin: round; }

/* phones: a popular title shows a flame, in the colour of its dot, instead of the dot */
.dots { align-items: center; }
.dots i.hot {
  width: 0.9rem; height: 0.9rem; border-radius: 0; background: var(--cat);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='3 2 18 20'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='3 2 18 20'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* hover on a popular entry: flickering flame, rising sparks, pulsing halo on the pill */
@keyframes flame-flick { 0%, 100% { transform: scale(1, 1) rotate(0); } 20% { transform: scale(0.92, 1.1) rotate(-5deg); } 45% { transform: scale(1.07, 0.94) rotate(4deg); } 70% { transform: scale(0.95, 1.07) rotate(-3deg); } }
@keyframes flame-spark { 0% { opacity: 0; transform: translateY(0) scale(1); } 20% { opacity: 1; } 100% { opacity: 0; transform: translateY(-0.9rem) scale(0.3); } }
@keyframes pop-halo { 0%, 100% { box-shadow: 0 0 0 0 transparent; } 50% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--pop-bd) 35%, transparent); } }
@media (prefers-reduced-motion: no-preference) {
  .entry:focus-visible .pop-fl svg { animation: flame-flick 0.7s ease-in-out infinite; }
  .entry:focus-visible .pop-fl i { animation: flame-spark 1s ease-out infinite; }
  .entry:focus-visible .pop-fl i:nth-of-type(2) { animation-delay: 0.3s; }
  .entry:focus-visible .pop-fl i:nth-of-type(3) { animation-delay: 0.6s; }
  .entry:focus-visible .pop-pill { animation: pop-halo 1.2s ease-in-out infinite; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .entry:hover .pop-fl svg, .card:hover .flame svg, .pill:hover .flame svg { animation: flame-flick 0.7s ease-in-out infinite; }
  .entry:hover .pop-fl i { animation: flame-spark 1s ease-out infinite; }
  .entry:hover .pop-fl i:nth-of-type(2) { animation-delay: 0.3s; }
  .entry:hover .pop-fl i:nth-of-type(3) { animation-delay: 0.6s; }
  .entry:hover .pop-pill { animation: pop-halo 1.2s ease-in-out infinite; }
}

/* copies of the titles that were just filtered out: they fade away where they were, above the page, never clickable */
.tl-ghosts { position: fixed; inset: 0; z-index: 5; overflow: hidden; pointer-events: none; list-style: none; } /* the copies are <li> outside their list: no bullet */
#tl-list { overflow-anchor: none; } /* the app keeps the topmost day in place itself (tlRestoreAnchor) */
