/* ================================================================
   VOCAB PAGE — standalone /vocab/ page
   Styles for layouts/_default/vocab.html
   Only loaded on /vocab/, mirroring how reader.css is scoped to
   /reader/ (see that file's own header comment) — safe to leave these
   selectors unscoped since the file itself is page-specific.
   ================================================================ */

/* theme.scss's base ".post" rule (article.post.page, the header's own
   wrapper) gives it 4rem top / 1em bottom padding meant for NORMAL-FLOW
   content — but the header inside is position:fixed (removed from flow
   entirely), so that padding just becomes dead space nothing needs,
   while still pushing whatever comes AFTER the article (the carousel)
   down by that same amount on top of its own header-clearance margin.
   Zeroed here, scoped to this page only. */
body.vocab-standalone-page article.post.page {
  padding: 0;
  height: auto;
}

/* ── Fixed header shell: has to stay visible above the auto-opened
   overlay (vocab-page.js), which is position:fixed/inset:0 at z-index
   99999 — a normal in-flow header like reader's would just get covered
   the instant the overlay opens. left:0/right:0 makes it full-bleed
   (unlike reader's centered 700px column), so its own padding — not
   theme.scss's ".page-template .post-header" rule, which only spaces
   the block, not the viewport edges — is what keeps its contents off
   the true screen edges. ── */

#vocab-page-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100000;
  background: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
  margin: 0;
  padding: 1.1rem 2.5rem 0.8rem;
}

#vocab-page-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

/* ── Back link + language menu: same colors/font as reader.css's
   version, re-supplied here for the same reason reader.css re-supplies
   them — #site-languages is normally scoped to #site-head on the
   homepage and doesn't reach a standalone page on its own. ── */

#back-to-main-page {
  font-family: "Lexend", sans-serif;
  color: #14161a;
  text-decoration: none;
  white-space: nowrap;
  /* Pushed in from the header's own edge padding above, not flush
     against it — the original ask this rule exists for. */
  margin-left: 0.5rem;
}

/* content.scss's global "a:hover { color: var(--sticky-menu-text-color) }"
   (the green seen on /apps/ and /reader/) gets beaten here by the fixed
   #back-to-main-page color above, since an ID selector always outranks a
   plain "a:hover" — same fix needed to restore that hover on this page. */
#back-to-main-page:hover {
  color: var(--sticky-menu-text-color);
}

#site-languages {
  position: relative;
  text-align: right;
  margin-bottom: 0;
}

#site-languages .btn-lang {
  text-decoration: none;
  background-color: #FFFF33;
  color: #3333FF;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  display: inline-block;
  font-size: 70%;
  line-height: 1;
  margin: 0 0 0 0.7rem;
  padding: 0.3rem 0.7rem;
  position: relative;
  text-transform: uppercase;
  font-family: "Oswald", sans-serif;
}

#site-languages .btn-lang.active,
#site-languages .btn-lang:hover {
  color: #D4FF00;
  background-color: #2B00FF;
}

/* ── Collapsed dropdown trigger — inert above the MOBILE breakpoint below,
   where #lang-dropdown instead renders flat as the plain pill row (the
   original look, same fix as reader.css's copy of this pattern). Below it,
   this becomes the only visible piece and #lang-dropdown becomes an
   absolutely-positioned panel toggled by it. ── */

#lang-trigger {
  display: none;
}

#lang-dropdown {
  display: contents;
}

/* ── Language switcher collapses into a globe-icon trigger + dropdown
   panel here instead of the flat pill row wrapping across lines. Same
   pattern/values as reader.css's copy; toggle wiring is a matching
   listener block in vocab-page.js. ── */

@media only screen and (max-width: 640px) {
  #lang-trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background-color: #FFFF33;
    color: #3333FF;
    border: none;
    border-radius: 5px;
    box-sizing: content-box;
    height: 1em;
    line-height: 1;
    padding: 0.3rem 0.7rem;
    font-size: 70%;
    font-family: "Oswald", sans-serif;
    text-transform: uppercase;
    cursor: pointer;
  }

  #lang-trigger .lang-trigger-icon-svg {
    width: 1.5em;
    height: 1.5em;
    flex-shrink: 0;
  }

  #lang-trigger .lang-trigger-caret {
    font-size: 0.8em;
    transition: transform 0.2s ease;
  }

  #site-languages.open #lang-trigger {
    color: #D4FF00;
    background-color: #2B00FF;
  }

  #site-languages.open #lang-trigger .lang-trigger-caret {
    transform: rotate(180deg);
  }

  #lang-dropdown {
    display: none;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 0.5rem;
    padding: 0.75rem;
    background: #fff;
    border-radius: 0.75rem;
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.25);
    z-index: 1000;
  }

  #site-languages.open #lang-dropdown {
    display: flex;
  }

  #lang-dropdown .btn-lang {
    margin: 0;
  }
}

/* ── Relocated title: custom.css's .vocab-mobile-title rule (plain
   class selector, not scoped to the overlay) still applies wherever
   the element lives, so this only trims it down from the overlay's
   own 4rem hero size to something that fits a slim persistent bar. ── */

/* Matches Speed Reader's .post-title, which has no size of its own and
   just falls back to the theme's global h1 rule (content.scss) — 5rem
   by default, 4.8rem at <=1130px (responsiveness.scss). Same two values
   here since .vocab-mobile-title's own custom.css rule (4rem, meant for
   the full-screen overlay) would otherwise win by specificity. */
#vocab-page-title-slot .vocab-mobile-title {
  font-size: 5rem;
  margin: 0.6rem 0 1rem;
}

@media only screen and (max-width: 1130px) {
  #vocab-page-title-slot .vocab-mobile-title {
    font-size: 4.8rem;
  }
}

/* ── Relocated category search: custom.css themes this box via
   ".vocab-mobile-overlay .vocab-search" (descendant) and
   ".vocab-mobile-overlay > .vocab-search--categories" (direct child) —
   both stop matching once the box is moved out of the overlay into the
   header, so its color variables and spacing are re-supplied here
   (same values) instead of falling back to the component's undyed
   defaults. ── */

#vocab-page-search-slot {
  display: flex;
  justify-content: center;
  margin-top: 0.4rem;
}

#vocab-page-search-slot .vocab-search--categories {
  width: 100%;
  max-width: 420px;
  padding: 0;
}

#vocab-page-search-slot .vocab-search {
  --vs-fg: #222;
  --vs-fg-dim: rgba(0, 0, 0, 0.4);
  --vs-bg: rgba(0, 0, 0, 0.04);
  --vs-border: rgba(0, 0, 0, 0.12);
  --vs-bg-focus: rgba(0, 0, 0, 0.07);
  --vs-border-focus: rgba(0, 0, 0, 0.35);
}

#vocab-page-search-slot .vocab-search-box { height: 42px; }

/* ── #vocab-mobile-overlay stays in its native `hidden` state on this
   page (vocab-page.js no longer force-opens it as a full-screen modal —
   the carousel below is what's actually shown). It's still present and
   fully queryable/manipulable via JS for its content (search index,
   carousel-selected category relocation), just never visually toggled
   open here, so no top-offset/close-button overrides are needed the way
   the old auto-opened-modal version required. ── */

/* The floating "open vocabulary menu" hamburger (mobile only,
   custom.css) would just re-open the same content this whole page
   already shows, in the old full-screen-modal form — redundant now that
   nothing here auto-opens it. Hidden only on this page; every other
   page still needs it as the only way to reach the vocab overlay. */
body.vocab-standalone-page #vocab-mobile-btn {
  display: none;
}

/* The desktop left-edge strips (#vocab-nav — Nouns/Verbs/Adjectives)
   are redundant here: those same three categories already appear as
   faces in the carousel below, alongside all the others. Belongs on the
   homepage only. Reclaiming the space custom.css normally reserves for
   them (body's own margin-left, >=769px) so nothing leaves an empty
   gap where the strips used to be. */
@media only screen and (min-width: 769px) {
  body.vocab-standalone-page {
    margin-left: 0;
  }
}

body.vocab-standalone-page #vocab-nav {
  display: none;
}

/* ================================================================
   CAROUSEL — migrated from the approved /test/ prototype (see
   carousel-prototype-test-page memory). Geometry/values below are
   tuned/approved, ported as-is — don't re-derive from scratch.
   custom.css's --vocab-* color variables are available here too
   (loaded site-wide via custom_head.html), reused below instead of
   redefining the palette.
   ================================================================ */

/* ── Viewport: the "window" the drum spins behind. perspective is what
   gives rotateX+translateZ actual depth instead of a flat stack.
   Deliberately NOT centered/capped, same as /test/'s original — body's
   margin-left is already zeroed on this page (see the strip-clearing
   rule above), so the viewport starts flush at the true left edge and
   runs to the screen edge on the right (minus a small inset), rather
   than being boxed in symmetrically. ── */
.carousel-outer {
  position: relative;
  /* Clears the fixed header — same custom property vocab-page.js's
     syncHeaderHeight() already maintains for the header's own height,
     reused here instead of a second measurement. */
  margin-top: var(--vocab-page-header-height, 160px);
}

.carousel-viewport {
  position: relative;
  height: 330px;
  margin: 0 2.5rem 2rem 0;
  perspective: 800px;
  perspective-origin: 50% 50%;
  overflow: hidden;
}

/* Soft top/bottom fade so faces don't hard-clip at the viewport edge */
.carousel-viewport::before,
.carousel-viewport::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 20px;
  z-index: 10;
  pointer-events: none;
}
.carousel-viewport::before {
  top: 0;
  background: linear-gradient(#fff, rgba(255, 255, 255, 0));
}
.carousel-viewport::after {
  bottom: 0;
  background: linear-gradient(rgba(255, 255, 255, 0), #fff);
}

.carousel-wheel {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  transform-style: preserve-3d;
  /* rotateX set inline by vocab-page.js as the user scrolls/drags */
  cursor: grab;
}
.carousel-wheel.is-dragging { cursor: grabbing; }

/* Fixed, uniform height — the drum's geometry (equal angle per face)
   only works cleanly if every face is the same size. Each face is just
   the ribbon bar (color/zh/en/count) — the real subgroup content isn't
   duplicated per face at all (see vocab-page.js), so there's no hidden
   per-face data weighing this down the way /test/'s prototype had. */
.carousel-face {
  position: absolute;
  /* Centered ON the wheel's rotation axis (top: 50% of the wheel, which
     itself has ~0 intrinsic height since its children are all
     absolutely positioned) rather than starting AT it. A face
     positioned top:0/height:64px would rotate around ITS OWN center —
     32px below the wheel's actual axis — and that mismatch between the
     two rotation origins is exactly what reads as the whole drum
     bobbing up and down while spinning instead of holding still.
     -32px must stay at half of the 64px height below (and the JS
     faceHeight constant) if either ever changes. */
  top: 50%;
  margin-top: -32px;
  left: 0;
  width: 100%;
  height: 64px;
  box-sizing: border-box;
  padding: 0 2.5rem;
  display: flex;
  align-items: center;
  color: #fff;
  font-family: "Oswald", sans-serif;
  cursor: pointer;
  backface-visibility: hidden;
  transition: box-shadow 0.2s, filter 0.2s;
}

/* Same "light up" as the desktop strip tabs (.vocab-strip-tab:hover in
   custom.css) — filter: brightness rather than a background-color
   swap, so it works uniformly across all 16 categories' colors without
   needing a per-color hover value. */
.carousel-face:hover {
  filter: brightness(1.12);
}

.carousel-face.is-selected {
  box-shadow: inset 0 0 0 3px #fff;
}

/* zh / en / count as one centered group, not spread edge-to-edge. */
.carousel-face-summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.8rem;
  width: 100%;
  text-align: center;
}

.carousel-face-zh {
  font-family: serif;
  font-size: 1.3rem;
  font-weight: 600;
}

.carousel-face-en {
  font-size: 0.85rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  opacity: 0.85;
}

.carousel-face-count {
  font-size: 0.75rem;
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
}

/* ── Category colors — reusing custom.css's --vocab-* variables instead
   of redefining the palette here. Text-color pairing (white vs each
   color's own -dark var) matches the same per-category choice used
   throughout the rest of the site (.vocab-mobile-summary etc.), not a
   fresh call made just for this component. ── */

.carousel-face.vocab-red     { background: var(--vocab-red); }
.carousel-face.vocab-orange  { background: var(--vocab-orange); }
.carousel-face.vocab-yellow  { background: var(--vocab-yellow); color: var(--vocab-yellow-dark); }
.carousel-face.vocab-cream   { background: var(--vocab-cream); color: var(--vocab-cream-dark); }
.carousel-face.vocab-green   { background: var(--vocab-green); }
.carousel-face.vocab-aqua    { background: var(--vocab-aqua); color: var(--vocab-aqua-dark); }
.carousel-face.vocab-blue    { background: var(--vocab-blue); }
.carousel-face.vocab-violet  { background: var(--vocab-violet); }
.carousel-face.vocab-magenta { background: var(--vocab-magenta); }
.carousel-face.vocab-pink    { background: var(--vocab-pink); color: var(--vocab-pink-dark); }
.carousel-face.vocab-brown   { background: var(--vocab-brown); }
.carousel-face.vocab-gray    { background: var(--vocab-gray); }
.carousel-face.vocab-black   { background: var(--vocab-black); }
.carousel-face.vocab-white   { background: var(--vocab-white); color: var(--vocab-white-dark); }
.carousel-face.vocab-burgundy { background: var(--vocab-burgundy); }
.carousel-face.vocab-silver  { background: var(--vocab-silver); color: var(--vocab-silver-dark); }

/* ── Detail panel — the selected category's real subgroups (full word
   lists + flashcards, relocated from the hidden overlay by
   vocab-page.js, not cloned/duplicated). Positioned absolutely within
   .carousel-outer (not .carousel-viewport, which clips via
   overflow:hidden) so it can extend past the viewport's own 640px
   without being cut off, while its "top" — set by vocab-page.js — still
   lines up with the bottom edge of whichever face is centered right
   now. Opaque background + z-index is what makes it cover the other
   faces still rotated into view below that point, on purpose. No
   max-height/overflow anywhere in this chain, so a 25-subgroup category
   just runs the page taller instead of getting clipped. ── */

.carousel-detail {
  position: absolute;
  left: 0;
  right: 2.5rem;
  z-index: 50;
  background: #fff;
  padding: 1.5rem 0 3rem;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  font-family: "Open Sans", sans-serif;
}

.carousel-detail-title {
  font-family: "Oswald", sans-serif;
  font-size: 1.3rem;
  letter-spacing: 1px;
  margin: 0 0 1rem;
  color: #14161a;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .carousel-wheel { transition: none !important; }
}
