:root {
  --bg: #f3f4f6; --card: #ffffff; --border: #e5e7eb; --ink: #1f2937; --muted: #6b7280;
  /* The four mode lights, all on the shared accent recipe (4.60:1).
     Study=blue  Learn=green  Sprint=violet  Match=amber. The marquee
     down each edge chases these same four, so it doubles as the legend. */
  --accent: #2a6df2; --accent-soft: #eff5ff;
  --accent2: #218640; --accent2-soft: #e7fbea;
  --accent3: #9c46f3; --accent3-soft: #f7f2ff;
  --accent4: #ad631e; --accent4-soft: #fff2e8;
  --surface-accent: #9c46f3;   /* Arcade's own identity hue: violet = play */
  --shadow: 0 2px 4px rgba(16,20,28,.04), 0 8px 20px rgba(16,20,28,.06);
  --shadow-lift: 0 6px 12px rgba(16,20,28,.06), 0 20px 44px rgba(16,20,28,.09);
}
:root[data-theme="dark"] {
  --bg: #0f1115; --card: #191c22; --border: #2a2e37; --ink: #e5e7eb; --muted: #9aa1ac;
  --accent: #4981ee; --accent-soft: #14223d;
  --accent2: #31974d; --accent2-soft: #0c2a13;
  --accent3: #a465ee; --accent3-soft: #281c39;
  --accent4: #c0722d; --accent4-soft: #361b04;
  --surface-accent: #a465ee;
  --shadow: 0 2px 4px rgba(0,0,0,.40), 0 8px 20px rgba(0,0,0,.46);
  --shadow-lift: 0 6px 12px rgba(0,0,0,.46), 0 20px 44px rgba(0,0,0,.56);
}
/* Ambient background gradient drift (added 2026-07-17), covers Arcade +
   all 4 modes since they share this stylesheet. Wins over the plain `body
   { background: var(--bg); }` rule below by specificity (data-theme
   attribute selector beats a bare element selector). Each seasonal block
   below drifts with that season's own palette instead -- see
   [[pa-quizzes-seasonal-themes]].
   Recolored 2026-07-17 (same day, twice): first pass cycled through the
   muted --accent/N-soft badge tints, but that read as barely different
   from the rest of the site's neutral tint. Second pass (user: "more
   pronounced and lively... think Vegas") blends the FULL-strength
   --accent/2/3/4 colors themselves via color-mix() -- deep saturated glow
   against black in dark mode, bold candy tones in light mode -- instead of
   their pre-muted -soft counterparts, while still cycling through the same
   four mode colors for consistency with the marquee lights/badges. */
/* Interpolated in oklab, not srgb. Mixing saturated hues through sRGB
   drags every midpoint toward grey -- that muddy band between the stops was
   what made this read cheap, not the saturation itself. oklab keeps the
   transitions clean, so the colour stays vivid the whole way round.
   A second, static layer adds a vertical lightness falloff so the page has
   depth instead of sitting at one flat mid-tone. */
:root[data-theme="dark"] body {
  background:
    linear-gradient(to bottom, rgba(255,255,255,.05), rgba(0,0,0,.20)),
    linear-gradient(in oklab 120deg,
      color-mix(in oklab, var(--accent) 35%, black),
      color-mix(in oklab, var(--accent2) 35%, black),
      color-mix(in oklab, var(--accent3) 35%, black),
      color-mix(in oklab, var(--accent4) 35%, black),
      color-mix(in oklab, var(--accent) 35%, black));
  background-color: var(--bg);   /* AFTER the shorthand -- placing it before lets the shorthand reset it back to transparent */
  background-size: 100% 100%, 400% 400%;
  background-attachment: fixed, scroll;
  animation: bg-drift 26s ease-in-out infinite;
}
:root[data-theme="light"] body {
  background:
    linear-gradient(to bottom, rgba(255,255,255,.34), rgba(255,255,255,0) 42%, rgba(20,14,40,.07)),
    linear-gradient(in oklab 120deg,
      color-mix(in oklab, var(--accent) 42%, white),
      color-mix(in oklab, var(--accent2) 42%, white),
      color-mix(in oklab, var(--accent3) 42%, white),
      color-mix(in oklab, var(--accent4) 42%, white),
      color-mix(in oklab, var(--accent) 42%, white));
  background-color: var(--bg);   /* AFTER the shorthand -- placing it before lets the shorthand reset it back to transparent */
  background-size: 100% 100%, 400% 400%;
  background-attachment: fixed, scroll;
  animation: bg-drift 26s ease-in-out infinite;
}
@keyframes bg-drift {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}
/* Seasonal light-mode tints (see theme.js for the date windows that add
   these body classes) -- explicitly scoped to [data-theme="light"] so
   they never fire in dark mode, same pattern as index.html's homepage
   overrides in theme.css. */
:root[data-theme="light"] body.vday-theme {
  --bg: #fbe7ee; --card: #fffcfd; --border: #f0cddb;
  background: linear-gradient(120deg, #fbe7ee, #fef0f7, #f5d3e0, #fbe7ee);
  background-color: #fbe7ee;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.fall-theme {
  --bg: #fdf1e4; --card: #fffdf8; --border: #f0dcc0;
  background: linear-gradient(120deg, #fdf1e4, #fef8ef, #f8dfc0, #fdf1e4);
  background-color: #fdf1e4;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.stpatricks-theme {
  --bg: #d7f0dd; --card: #f9fefb; --border: #a9dab8;
  background: linear-gradient(120deg, #d7f0dd, #e9f9ec, #bfe8ca, #d7f0dd);
  background-color: #d7f0dd;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.xmas-theme {
  --bg: #faf3e3; --card: #fffdf7; --border: #ece0c4;
  background: linear-gradient(120deg, #faf3e3, #fffcf3, #f3e4c4, #faf3e3);
  background-color: #faf3e3;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.paweek-theme {
  --bg: #e7f6f4; --card: #fbfffe; --border: #c7e7e1;
  background: linear-gradient(120deg, #e7f6f4, #f2fbf9, #d4edf2, #e7f6f4);
  background-color: #e7f6f4;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.halloween-theme {
  --bg: #f1e9f6; --card: #fefcff; --border: #dccbea;
  background: linear-gradient(120deg, #f1e9f6, #f8f1fb, #f6dcc6, #f1e9f6);
  background-color: #f1e9f6;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.fireworks-theme {
  --bg: #eef3fb; --card: #fbfdff; --border: #cdd9ee;
  background: linear-gradient(120deg, #eef3fb, #fbf1f1, #e0eaf9, #eef3fb);
  background-color: #eef3fb;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.newyear-theme {
  --bg: #eef0f6; --card: #fefeff; --border: #d3d8e8;
  background: linear-gradient(120deg, #eef0f6, #f8f4e8, #e2e6f2, #eef0f6);
  background-color: #eef0f6;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
:root[data-theme="light"] body.thanksgiving-theme {
  --bg: #fdf6e8; --card: #fffefa; --border: #efe0bc;
  background: linear-gradient(120deg, #fdf6e8, #fffaf0, #f8ebc9, #fdf6e8);
  background-color: #fdf6e8;
  background-size: 300% 300%;
  animation: bg-drift 16s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  /* !important needed: the :root[data-theme=...]-scoped drift rules above
     are more specific than a plain class selector can match without it. */
  body, body.vday-theme, body.fall-theme, body.stpatricks-theme, body.xmas-theme, body.paweek-theme, body.halloween-theme, body.thanksgiving-theme, body.newyear-theme, body.fireworks-theme {
    animation: none !important;
    background-position: 0% 50% !important;
  }
}
* { box-sizing: border-box; }
body {
  margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg); color: var(--ink); transition: background .2s, color .2s;
  -webkit-font-smoothing: antialiased;
}

/* Arcade-cabinet marquee lights down each edge -- a column of dots cycling
   through the same 4 accent colors as Study/Learn/Sprint/Match, twinkling
   like cabinet trim lighting, instead of the real site's clinical EKG
   zigzag (fitting there, not here). Built as a live inline SVG rather than
   a baked data-URI so it follows the manual dark-mode toggle. */
@keyframes decor-pulse-intro {
  0% { opacity: 0; }
  25% { opacity: 0.55; }
  50% { opacity: 0.08; }
  75% { opacity: 0.4; }
  100% { opacity: 0.18; }
}
@keyframes dot-twinkle {
  0%, 100% { opacity: .45; }
  50% { opacity: 1; }
}
.edge-decor {
  /* height:100vh (not bottom:0) -- <svg> is a replaced element, and a fixed
     replaced element with both top and bottom set falls back to its
     intrinsic size (300x150 default) instead of stretching, silently
     ignoring bottom. An explicit height sidesteps that entirely. */
  /* z-index above theme.css's settings/shortcuts/sign-in overlays (all
     z-index: 2000) so the marquee dots stay visible through them instead of
     getting dimmed by the modal backdrop -- they're decorative chrome, not
     page content a modal needs to obscure. */
  position: fixed; top: 0; width: 74px; height: 100vh;
  opacity: 0.18; pointer-events: none; z-index: 2001; display: none;
  animation: decor-pulse-intro 2.2s ease-in-out 1;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 32%, black 68%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, black 32%, black 68%, transparent 100%);
}
/* Bulbs are addressed by class, not nth-of-type -- the pattern now holds
   halos and filler bulbs as well, so positional selectors no longer line up
   with the four mode lights. .i1-.i4 stagger the chase down the column. */
.edge-decor .mq-bulb, .edge-decor .mq-fill { animation: dot-twinkle 2.4s ease-in-out infinite; }
.edge-decor .mq-halo { opacity: 0; }
.edge-decor .i2 { animation-delay: .3s; }
.edge-decor .i3 { animation-delay: .6s; }
.edge-decor .i4 { animation-delay: .9s; }
@media (prefers-reduced-motion: reduce) {
  .edge-decor, .edge-decor circle { animation: none; }
}
.edge-decor.left { left: 0; }
.edge-decor.right { right: 0; transform: scaleX(-1); }
@media (min-width: 1000px) {
  .edge-decor { display: block; }
}
/* Homescreen-only marquee boost (arcade.html specifically, via the
   .flash-strong modifier -- the other 4 arcade pages keep the subtler
   base .edge-decor twinkle above). Swaps the one-time intro pulse for a
   continuous glow, and pushes each dot's twinkle into a real on/off flash
   with a longer stagger so the 4-color sequence reads as chasing down the
   column rather than just shimmering in place. */
@keyframes homescreen-edge-glow {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 0.9; }
}
@keyframes dot-flash-strong {
  0%, 100% { opacity: .22; }
  45% { opacity: 1; }
}
/* The halo swells and fades as the chase passes, so a lit bulb reads as
   actually glowing rather than just brightening -- geometry, not a filter,
   because filters on <pattern> children don't render reliably. */
@keyframes bulb-halo {
  0%, 100% { opacity: 0; transform: scale(.55); }
  45%      { opacity: .38; transform: scale(1); }
}
@keyframes fill-flash {
  0%, 100% { opacity: .14; }
  45%      { opacity: .55; }
}
.edge-decor.flash-strong {
  animation: homescreen-edge-glow 2.6s ease-in-out infinite;
}
.edge-decor.flash-strong .mq-bulb { animation: dot-flash-strong 1.8s ease-in-out infinite; }
.edge-decor.flash-strong .mq-fill { animation: fill-flash 1.8s ease-in-out infinite; }
.edge-decor.flash-strong .mq-halo {
  animation: bulb-halo 1.8s ease-in-out infinite;
  transform-box: fill-box;
  transform-origin: center;
}
.edge-decor.flash-strong .i1 { animation-delay: 0s; }
.edge-decor.flash-strong .i2 { animation-delay: .45s; }
.edge-decor.flash-strong .i3 { animation-delay: .9s; }
.edge-decor.flash-strong .i4 { animation-delay: 1.35s; }
@media (prefers-reduced-motion: reduce) {
  .edge-decor.flash-strong,
  .edge-decor.flash-strong .mq-bulb,
  .edge-decor.flash-strong .mq-fill { animation: none; opacity: .18; }
  .edge-decor.flash-strong .mq-halo { animation: none; opacity: 0; }
}
.page {
  max-width: 640px; margin: 0 auto; padding: 28px 22px 60px; position: relative;
  animation: page-in .35s cubic-bezier(.2,.7,.3,1) both;
}
.page.page-home { max-width: 1100px; }
.page.page-wide { max-width: 1100px; }
@keyframes page-in {
  from { opacity: 0; transform: translateY(6px); }
}
@media (prefers-reduced-motion: reduce) {
  .page { animation: none; }
}
@media (min-width: 860px) {
  .deck-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; align-items: start; }
  .deck-grid .deck-card { margin-bottom: 0; }
}

.semester-header {
  font-size: 15px; font-weight: 800; color: var(--muted); text-transform: uppercase;
  letter-spacing: .06em; margin: 0 0 14px; text-align: center;
}
.tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
  /* One scrolling chip row on phones (design review item 18, 2026-09-25):
     the chips used to stack seven rows and push the content a screen down. The
     row bleeds to the screen edges, snaps chip by chip, and fades at both
     ends so it reads as scrollable. The homepage class tabs deliberately
     WRAP (resolved_site_bugs) and are not touched. */
  @media (max-width: 640px) {
    .tabs {
      flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
      scroll-snap-type: x proximity; scroll-padding: 0 16px;
      margin-left: -16px; margin-right: -16px; padding: 4px 16px 10px;
      scrollbar-width: none;
      -webkit-mask-image: linear-gradient(to right, transparent 0, #000 14px, #000 calc(100% - 28px), transparent 100%);
      mask-image: linear-gradient(to right, transparent 0, #000 14px, #000 calc(100% - 28px), transparent 100%);
    }
    .tabs::-webkit-scrollbar { display: none; }
    .tabs .tab-btn { flex: none; white-space: nowrap; scroll-snap-align: start; box-shadow: none; }  /* a shadow clipped by the scroll box reads as a grey band */
  }
.tab-btn {
  border: 1px solid var(--border); background: var(--card); color: var(--muted);
  border-radius: 12px; padding: 10px 16px; font: inherit; font-size: 14px; font-weight: 700;
  cursor: pointer; transition: background .15s, color .15s, border-color .15s;
}
.tab-btn:hover { border-color: var(--accent); color: var(--ink); }
.tab-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.tab-panel { display: none; }
.tab-panel.active { display: block; }

.exam-section {
  background: var(--card); border: 1px solid var(--border); border-radius: 16px;
  margin-bottom: 14px; box-shadow: var(--shadow); overflow: hidden;
}
.exam-section summary {
  list-style: none; cursor: pointer; padding: 16px 18px; font-weight: 700; font-size: 15.5px;
  display: flex; align-items: center; justify-content: space-between;
}
.exam-section summary::-webkit-details-marker { display: none; }
.exam-section summary::after {
  content: ""; width: 9px; height: 9px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg); transition: transform .2s; flex: none;
}
.exam-section[open] summary::after { transform: rotate(45deg); }
.exam-content { padding: 4px 18px 18px; }
.exam-content .deck-card:last-child { margin-bottom: 0; }

.proto-badge {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .02em; color: var(--muted); background: var(--card); border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 12px 5px 10px; margin-bottom: 18px; box-shadow: var(--shadow);
}
.proto-badge svg { flex: none; color: var(--accent3); }

.brand-row { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 6px; }
.brand { display: flex; align-items: center; gap: 12px; }
.brand-mark {
  width: 44px; height: 44px; border-radius: 13px;
  background: linear-gradient(135deg, var(--accent), var(--accent3));
  color: #fff; display: flex; align-items: center; justify-content: center; flex: none;
  box-shadow: 0 3px 10px -2px color-mix(in srgb, var(--accent3) 55%, transparent);
  transition: transform .25s var(--ease-spring);
}
.brand:hover .brand-mark { transform: rotate(-8deg) scale(1.06); }
.brand-text h1 {
  font-size: 29px; font-weight: 800; margin: 0; letter-spacing: -.01em; line-height: 1.1;
  background: linear-gradient(90deg, var(--ink), var(--accent3) 150%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.brand-text p { margin: 3px 0 0; font-size: 14.5px; color: var(--muted); font-weight: 500; }

/* #corner-actions (theme.js/theme.css) stays fixed at the top-right of the
   viewport like every other page -- just pulled in far enough that it
   clears the 74px edge-decor dot column instead of sitting on top of it. */
@media (min-width: 1000px) {
  #corner-actions { right: 98px; }
}

.streak-pill {
  /* gap:0 -- the flex gap used to fall between the count and the "-day
     streak" label, rendering as "0 -day streak". Only the flame needs
     separating from the text, so it carries the spacing itself. */
  display: inline-flex; align-items: center; gap: 0; background: var(--card);
  border: 1px solid var(--border); border-radius: 999px; padding: 7px 16px 7px 12px;
  font-weight: 700; font-size: 14px; box-shadow: var(--shadow); margin: 16px 0 22px;
}
.streak-pill .flame { font-size: 15px; display: inline-flex; margin-right: 7px; color: var(--accent4); animation: flame-pulse 1.6s ease-in-out infinite; }
@keyframes flame-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.15); }
}
@media (prefers-reduced-motion: reduce) {
  .streak-pill .flame { animation: none; }
}
.streak-pill span { color: var(--muted); font-weight: 600; }
.streak-pill b { color: var(--ink); font-weight: 800; }
.streak-pill.is-empty .flame { animation: none; }

/* Exam rows that say something (design review item 15): deck count, cards
   due, and the four mode lights -- Study / Learn / Sprint / Match, the same
   four colours as the marquee, so no new colour. */
.exam-section summary .exam-title { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.exam-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.exam-meta .due { color: var(--ink); }
.mode-dots { display: inline-flex; gap: 4px; }
.mode-dots i { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }
.mode-dots .m1 { background: var(--accent); }
.mode-dots .m2 { background: var(--accent2); }
.mode-dots .m3 { background: var(--accent3); }
.mode-dots .m4 { background: var(--accent4); }
.exam-section.is-soon summary { color: var(--muted); }
.empty-state .big .si { color: var(--muted); }
.empty-state.soon { text-align: left; display: flex; gap: 12px; align-items: flex-start; padding: 6px 2px 4px; }
.empty-state.soon p { margin: 0; }
.empty-state.soon .big { font-size: 0; margin: 0; }

.deck-card {
  background: var(--card); border: 1px solid var(--border); border-top-width: 4px;
  border-radius: 18px; padding: 18px; margin-bottom: 14px; box-shadow: var(--shadow);
  transition: transform .15s var(--ease), box-shadow .15s var(--ease);
}
.deck-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
.deck-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.deck-name-row { display: flex; align-items: center; gap: 11px; }
.deck-icon {
  width: 42px; height: 42px; border-radius: 12px; display: flex; align-items: center;
  justify-content: center; flex: none;
  transition: transform .25s var(--ease-spring);
}
.deck-card:hover .deck-icon { transform: rotate(-8deg) scale(1.1); }
@media (prefers-reduced-motion: reduce) {
  .deck-card, .deck-icon { transition: none; }
  .deck-card:hover { transform: none; }
  .deck-card:hover .deck-icon { transform: none; }
}
.deck-name { font-size: 18px; font-weight: 700; }
.deck-count { font-size: 12.5px; color: var(--muted); font-weight: 600; margin-top: 2px; }
.due-badge {
  font-size: 12px; font-weight: 800; padding: 5px 12px; border-radius: 999px; flex: none;
  letter-spacing: .01em; margin-top: 2px;
}
.due-badge.some { background: var(--accent-soft); color: var(--accent); }
.due-badge.none { background: var(--accent2-soft); color: var(--accent2); }

.mastery-bar { display: flex; height: 9px; border-radius: 999px; overflow: hidden; margin: 16px 0 7px; background: var(--border); }
.mastery-seg { transition: width .4s var(--ease); }
.mastery-seg.new { background: var(--muted); opacity: .45; }
.mastery-seg.learning { background: #f59e0b; }
.mastery-seg.mastered { background: var(--accent2); }
.mastery-labels {
  display: flex; justify-content: space-between; font-size: 11px; color: var(--muted);
  font-weight: 600; margin-bottom: 16px; text-transform: uppercase; letter-spacing: .03em;
}

.deck-actions { display: flex; gap: 8px; }
.btn {
  flex: 1; border: none; border-radius: 12px; padding: 13px 16px; font-weight: 700;
  font-size: 15px; cursor: pointer; font-family: inherit; display: flex; align-items: center;
  justify-content: center; gap: 7px; transition: transform .18s var(--ease-spring), filter .12s, opacity .12s, box-shadow .18s;
  text-decoration: none;
}
.btn.primary { background: var(--accent); color: #fff; }
.btn.learn { background: var(--accent2); color: #fff; }
.btn.sprint { background: var(--accent3); color: #fff; }
.btn.match { background: var(--accent4); color: #fff; }
.btn.ghost { background: transparent; border: 1px solid var(--border); color: var(--ink); }
.btn:not(.ghost):hover { filter: brightness(1.08); transform: translateY(-2px); box-shadow: 0 8px 16px -6px rgba(0,0,0,.35); }
.btn.ghost:hover { filter: none; border-color: var(--accent); color: var(--accent); }
.btn:active { transform: scale(0.97); }
.deck-actions + .deck-actions { margin-top: 8px; }

.view { display: none; }
.view.active { display: block; }

.back-link {
  background: none; border: none; color: var(--muted); font-size: 14px; cursor: pointer;
  padding: 4px 0 18px; font-weight: 600; display: flex; align-items: center; gap: 4px;
  transition: color .15s; text-decoration: none; width: fit-content;
}
.back-link:hover { color: var(--ink); transform: translateX(-2px); }

.study-toolbar { display: flex; gap: 8px; margin-bottom: 14px; }
.study-tool-btn {
  flex: none; border: 1px solid var(--border); background: var(--card); color: var(--ink);
  border-radius: 999px; padding: 8px 14px; font-weight: 700; font-size: 13px; cursor: pointer;
  font-family: inherit; display: flex; align-items: center; gap: 6px; transition: filter .12s, border-color .12s, background .12s;
}
.study-tool-btn:hover { border-color: var(--accent); color: var(--accent); }
.study-tool-btn svg { flex: none; }
.study-tool-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.study-tool-btn.active:hover { color: #fff; filter: brightness(1.08); }
.study-tool-btn:disabled { opacity: .4; cursor: not-allowed; }
.study-tool-btn:disabled:hover { border-color: var(--border); color: var(--ink); }
.continuous-label {
  font-size: 12.5px; color: var(--accent); font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; display: flex; align-items: center; gap: 6px; margin-bottom: 8px;
}
.continuous-label .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); animation: continuous-pulse 1.4s ease-in-out infinite; }
@keyframes continuous-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

.session-progress { margin-bottom: 16px; }
.study-progress {
  font-size: 12.5px; color: var(--muted); font-weight: 700; margin-bottom: 8px;
  display: flex; justify-content: space-between; text-transform: uppercase; letter-spacing: .03em;
}
.progress-track { height: 7px; border-radius: 999px; background: var(--border); overflow: hidden; }
.progress-fill { height: 100%; background: var(--accent); border-radius: 999px; transition: width .3s var(--ease); width: 0%; }

.card-scene {
  perspective: 1200px; margin-bottom: 20px;
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}
.card-scene.no-anim { transition: none; }
.card-scene.exit-right { transform: translateX(130%) rotate(10deg); opacity: 0; }
.card-scene.exit-left { transform: translateX(-130%) rotate(-10deg); opacity: 0; }
.card-flip {
  position: relative; width: 100%; height: 560px; transform-style: preserve-3d;
  transition: transform .5s var(--ease); cursor: pointer;
}
.card-flip.no-anim { transition: none; }
.card-flip.flipped { transform: rotateY(180deg); }
.card-face {
  position: absolute; inset: 0; backface-visibility: hidden; border-radius: 28px;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 52px; font-size: 46px; font-weight: 700; line-height: 1.3;
}
.card-front { background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow-lift); }
.card-back { background: var(--accent-soft); border: 1px solid var(--accent); transform: rotateY(180deg); color: var(--ink); font-weight: 600; font-size: 34px; box-shadow: var(--shadow-lift); }
.flip-hint {
  position: absolute; bottom: 14px; left: 0; right: 0; text-align: center;
  font-size: 11px; color: var(--muted); font-weight: 600; display: flex;
  align-items: center; justify-content: center; gap: 4px; opacity: .8;
}
.flip-hint svg { flex: none; }

.rating-row { display: flex; gap: 12px; margin-bottom: 18px; }
.rating-btn {
  flex: 1; padding: 26px 4px; border-radius: 18px; border: none; font-weight: 800;
  font-size: 22px; color: #fff; cursor: pointer; display: flex; flex-direction: column;
  gap: 5px; align-items: center; transition: transform .12s, filter .12s;
}
.rating-btn:hover { filter: brightness(1.07); }
.rating-btn span.k { font-size: 13px; opacity: .82; font-weight: 700; letter-spacing: .02em; }
.rating-again { background: #dc2626; }
.rating-good { background: #218640; }
.rating-btn:active { transform: scale(0.95); }

.keyhint { font-size: 12px; color: var(--muted); text-align: center; margin-top: 8px; line-height: 1.5; }
.keyhint svg { vertical-align: -2px; margin: 0 1px; }

.empty-state {
  text-align: center; padding: 48px 24px; color: var(--muted);
  background: var(--card); border: 1px solid var(--border); border-radius: 20px; box-shadow: var(--shadow);
}
.empty-state .big { font-size: 40px; margin-bottom: 10px; }
.empty-state p { font-size: 15px; font-weight: 600; margin: 0; }

.learn-question {
  background: var(--card); border: 1px solid var(--border); border-radius: 28px;
  box-shadow: var(--shadow-lift); padding: 56px 40px; text-align: center; font-size: 42px;
  font-weight: 700; margin-bottom: 22px; min-height: 200px; display: flex; align-items: center;
  justify-content: center; line-height: 1.3;
}
.learn-choices { display: flex; flex-direction: column; gap: 14px; margin-bottom: 8px; }
.learn-choice {
  display: flex; align-items: center; gap: 16px; text-align: left; width: 100%;
  background: var(--card); border: 1.5px solid var(--border); border-radius: 16px;
  padding: 20px 24px; font: inherit; font-size: 20px; font-weight: 600; color: var(--ink);
  cursor: pointer; transition: border-color .12s, transform .1s, background .15s;
}
.learn-choice:hover:not(:disabled) { border-color: var(--accent); }
.learn-choice:active:not(:disabled) { transform: scale(0.99); }
.learn-choice .letter {
  width: 34px; height: 34px; border-radius: 10px; background: var(--bg); color: var(--muted);
  font-size: 16px; font-weight: 800; display: flex; align-items: center; justify-content: center; flex: none;
}
.learn-choice.correct { border-color: var(--accent2); background: var(--accent2-soft); }
.learn-choice.correct .letter { background: var(--accent2); color: #fff; }
.learn-choice.wrong { border-color: #dc2626; background: rgba(220,38,38,.08); }
.learn-choice.wrong .letter { background: #dc2626; color: #fff; }
.learn-choice:disabled { cursor: default; }

.sprint-intro { background: var(--card); border: 1px solid var(--border); border-radius: 18px; padding: 24px 20px; box-shadow: var(--shadow); text-align: center; }
.sprint-intro-icon {
  width: 56px; height: 56px; border-radius: 16px; background: var(--accent3-soft); color: var(--accent3);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 10px;
}
.sprint-intro h2 { margin: 4px 0 10px; font-size: 21px; }
.sprint-intro p { color: var(--muted); font-size: 14px; line-height: 1.55; margin: 0 0 4px; }
.sprint-diff-label { color: var(--muted); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; margin: 18px 0 8px !important; text-align: center; }

.sprint-race { display: flex; flex-direction: column; gap: 13px; margin: 4px 0 20px; }
.race-row { display: flex; align-items: center; gap: 11px; font-weight: 700; font-size: 14px; }
.race-avatar {
  width: 30px; height: 30px; border-radius: 9px; display: flex; align-items: center;
  justify-content: center; flex: none; color: #fff;
}
.race-avatar.you { background: var(--accent); }
.race-avatar.bot { background: var(--accent3); }
.race-track { flex: 1; height: 16px; background: var(--border); border-radius: 999px; overflow: hidden; }
.race-fill { height: 100%; border-radius: 999px; transition: width .3s ease-out; width: 0%; }
.race-fill.you { background: var(--accent); }
.race-fill.bot { background: var(--accent3); }
.race-score { width: 34px; text-align: right; flex: none; font-variant-numeric: tabular-nums; }

.sprint-timer {
  text-align: center; font-size: 44px; font-weight: 800; margin: 4px 0 12px;
  color: var(--ink); font-variant-numeric: tabular-nums; transition: color .2s;
}
.sprint-timer.low { color: #dc2626; }

.result-screen { text-align: center; padding: 16px 4px 4px; }
.result-icon {
  width: 64px; height: 64px; border-radius: 18px; display: flex; align-items: center;
  justify-content: center; margin: 0 auto 6px;
}
.result-icon.win { background: var(--accent2-soft); color: var(--accent2); }
.result-icon.lose { background: var(--accent3-soft); color: var(--accent3); }
.result-title { font-size: 26px; font-weight: 800; margin: 6px 0 4px; }
.result-sub { color: var(--muted); margin-bottom: 20px; font-weight: 600; }

.match-stats {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 22px;
  background: var(--card); border: 1px solid var(--border); border-radius: 16px;
  padding: 20px 28px; box-shadow: var(--shadow);
}
.match-stat { text-align: center; }
.match-stat .num {
  font-size: 32px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums;
  display: block; line-height: 1.2;
}
.match-stat .lbl { font-size: 12.5px; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.match-stat.best .num { color: var(--accent4); }

/* Progress bar, mirroring Notability's "1/12" bar above the cards. The timer
   and best-time stats stay -- this is still a speed run -- but the bar makes
   "how much is left" readable without doing arithmetic. */
.match-bar { display: flex; align-items: center; gap: 12px; margin: -8px 0 16px; }
.match-bar-track {
  flex: 1; height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--border);
}
.match-bar-fill {
  height: 100%; width: 0%; border-radius: 999px; background: var(--accent2);
  transition: width .35s var(--ease);
}
.match-bar-count {
  font-size: 13px; font-weight: 800; color: var(--muted);
  font-variant-numeric: tabular-nums; min-width: 58px; text-align: right;
}

/* Board-size control + fullscreen. */
.match-controls {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px; flex-wrap: wrap;
}
.match-size {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 13px; font-weight: 700; color: var(--muted);
}
.match-size input {
  width: 68px; padding: 7px 10px; border-radius: 10px; font: inherit;
  font-size: 15px; font-weight: 800; text-align: center; color: var(--ink);
  background: var(--card); border: 2px solid var(--border);
  font-variant-numeric: tabular-nums;
}
.match-size input:focus { outline: none; border-color: var(--accent4); }
.match-fs {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  padding: 8px 14px; border-radius: 10px; font: inherit; font-size: 13px;
  font-weight: 700; color: var(--muted);
  background: var(--card); border: 2px solid var(--border);
  transition: border-color .15s, color .15s;
}
.match-fs:hover { border-color: var(--accent4); color: var(--ink); }
.match-fs[hidden] { display: none; }

/* In fullscreen the page chrome is wasted height -- the whole point is to get
   more rows on screen -- so the branding, streak pill and back link fold away
   and the board takes the width. */
body.is-fullscreen .brand-row,
body.is-fullscreen .streak-pill,
body.is-fullscreen .back-link,
body.is-fullscreen .edge-decor,
body.is-fullscreen .keyhint { display: none; }
body.is-fullscreen .page { max-width: none; padding-top: 18px; }
body.is-fullscreen .match-stats { margin-bottom: 14px; padding: 14px 24px; }
body.is-fullscreen .match-item { min-height: 62px; padding: 16px 20px; }

/* Two columns -- terms on the left, definitions on the right, each shuffled
   independently -- matching how Notability's own Mix and Match works (tap a
   term, tap its definition; correct pairs turn green). Not a single mixed
   grid of both types. */
.match-columns { display: flex; gap: 24px; margin-bottom: 8px; align-items: flex-start; }
.match-col { flex: 1; display: flex; flex-direction: column; gap: 13px; min-width: 0; }
.match-col-label {
  font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); text-align: center; margin-bottom: 2px;
}
.match-item {
  background: var(--card); border: 2px solid var(--border); border-radius: 16px;
  padding: 22px 22px; min-height: 78px; display: flex; align-items: center; justify-content: center;
  text-align: center; font-size: 19px; font-weight: 700; color: var(--ink); cursor: pointer;
  line-height: 1.35; transition: border-color .15s, background .15s, color .15s, transform .2s var(--ease), opacity .25s var(--ease);
}
.match-item:hover:not(.matched):not(:disabled) { border-color: var(--accent4); }
.match-item.selected { border-color: var(--accent4); background: var(--accent4-soft); }
.match-item.correct { border-color: var(--accent2); background: var(--accent2-soft); color: var(--accent2); }
.match-item.wrong { border-color: #dc2626; background: rgba(220,38,38,.1); animation: match-shake .3s; }
.match-item.matched { opacity: 0; transform: scale(.9); pointer-events: none; }
.match-item.pop-in { animation: match-pop-in .3s cubic-bezier(.2,.7,.3,1) both; }
@keyframes match-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}
@keyframes match-pop-in {
  from { opacity: 0; transform: scale(.85); }
}
@media (max-width: 520px) {
  .match-item { font-size: 16px; padding: 16px 14px; min-height: 64px; }
  .match-columns { gap: 12px; }
  .match-col { gap: 10px; }
  .match-stats { padding: 14px 16px; }
  .match-stat .num { font-size: 24px; }
}

#toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  background: var(--ink); color: var(--bg); padding: 11px 20px; border-radius: 999px;
  font-size: 13px; font-weight: 600; opacity: 0; pointer-events: none; transition: opacity .25s;
  z-index: 50; white-space: nowrap; box-shadow: var(--shadow-lift);
}

.confetti-piece {
  position: fixed; top: -20px; width: 8px; height: 14px; z-index: 60; pointer-events: none;
  animation: confetti-fall linear forwards; border-radius: 2px;
}

@keyframes confetti-fall {
  to { transform: translateY(110vh) rotate(540deg); opacity: .3; }
}

/* Match the homepage's own treatment: #refresh-btn stays a visible
   standalone corner icon here too (theme.css hides it everywhere by
   default), instead of living inside the Settings panel -- see the
   matching isArcade skip in theme.js's initSettingsPanel(). */
#refresh-btn { display: flex; }

/* theme.css's modals (Settings, keyboard shortcuts, the cloud-sync sign-in
   prompt) dim the full viewport by default, which reaches into the edge
   marquee dots' 74px columns. Pull the dimmed area in from both sides at
   the same width the dots occupy (matching .edge-decor's own min-width:1000px
   breakpoint) so those columns stay fully undimmed instead of just relying
   on z-index to paint the dots on top of a still-darkened background. */
@media (min-width: 1000px) {
  .settings-overlay, .shortcuts-overlay, .tour-overlay {
    left: 74px;
    right: 74px;
  }
}
