/* v201: moved verbatim out of index.html's inline <style> — the strict CSP
   (style-src 'self') refuses <style> elements. Loaded at the same point in the
   cascade (after app.css, before canvas.css). Edit here, not in the page. */
/* R147: .pnav* moved to assets/app.css §18b — it's shared chrome every
   public page needs (faq/terms/privacy/install-app were rendering it
   unstyled because it used to live only here). Do not re-add it in this
   per-page block; edit assets/app.css instead. */

/* ===== Hero ===== */
.hero{padding:56px 5% 30px;display:grid;grid-template-columns:1fr;gap:38px;align-items:center;max-width:1400px;margin:0 auto}
@media(min-width:1020px){.hero{grid-template-columns:0.9fr 1.1fr;padding:72px 5% 40px}}
.hero-headline{font-size:clamp(34px,4.2vw,56px);font-weight:600;line-height:1.07;margin:14px 0 18px}
.hero-sub{font-size:15.5px;color:var(--text2);line-height:1.65;max-width:470px;margin-bottom:26px}
.hero-ctas{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:26px}
.trust-inline{display:flex;gap:26px;flex-wrap:wrap}
.ti{display:flex;flex-direction:column}
.ti b{font-family:var(--fm);font-size:21px;font-weight:700}
.ti span{font-size:11.5px;color:var(--text3);font-weight:600}

/* ===== Course rail (signature) ===== */
.rail-wrap{position:relative;min-width:0}
.rail-chips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:18px}
.rchip{font-size:12px;font-weight:600;padding:8px 16px;border-radius:var(--r-tag);background:var(--glass);border:1px solid var(--stroke);color:var(--text2);cursor:pointer;transition:all .2s;font-family:var(--fb)}
.rchip:hover{border-color:var(--stroke-hi);color:var(--text)}
.rchip.active{background:var(--brand);color:var(--brand-on);border-color:transparent}
.rchip.active.c-orange{background:var(--accent)}
.rchip.active.c-blue{background:var(--brand)}
.rchip.active.c-green{background:var(--jade)}
.rchip.active.c-all{background:var(--brand)}
/* R26 Pass 3: .rchip.active now carries a background of its own. It did not,
   and every background came from a .c-* modifier — but the HYDRATOR that
   rebuilds this rail emits `class="rchip active"` with no .c-* class at all,
   and the department chips it generates never get one either. So the active
   chip kept .rchip's translucent --glass background while taking
   color:var(--brand-on), which is dark ink: measured 1.00:1 in light and
   1.02:1 in dark. Invisible text on the landing page's primary filter, in the
   DEFAULT state, in both themes.
   Only the hydrated contrast audit could see it: the STATIC markup at line 191
   does carry .c-all, so every Pass 1 and Pass 2 contrast run measured a
   perfectly good chip and passed. This is the single best argument for the
   session fixture in tools/fixture.js. */
.rail{display:flex;gap:16px;overflow-x:auto;padding:14px 4px 22px;scroll-snap-type:x mandatory;scrollbar-width:none}
.rail::-webkit-scrollbar{display:none}
.ccard{min-width:252px;max-width:252px;scroll-snap-align:start;padding:0;overflow:hidden;transition:transform .28s cubic-bezier(.2,.7,.3,1.2),box-shadow .28s,border-color .28s;cursor:pointer;display:block}
/* R120: same trap as assets/app.css's own .btn.btn-x note just above the
   BUTTONS section — [data-theme="light"] a{color:var(--brand)} scores
   (0,1,1) and beats a single-class .ccard{color:...} at (0,1,0). The card is
   an <a> now (see the card() template below), so its title/price text would
   render link-blue without this. .ccard.glass scores (0,2,0) and wins
   cleanly — same fix, no !important, for the same reason. */
.ccard.glass{color:inherit;text-decoration:none}
.ccard:hover{box-shadow:var(--shadow);border-color:var(--stroke-hi)}
.ccard.hide{display:none}
.cc-thumb{height:112px;display:flex;align-items:center;justify-content:center;font-size:42px;position:relative;overflow:hidden}
.cc-thumb::after{content:none}
.t-blue{background:var(--surface-3)}
.t-orange{background:var(--surface-3)}
.t-green{background:var(--surface-3)}
.cc-body{padding:15px 16px 17px}
.cc-title{font-weight:600;font-size:13.5px;line-height:1.35;margin:7px 0 5px;min-height:36px}
.cc-meta{font-size:11.5px;color:var(--text3);font-weight:600;display:flex;gap:10px;margin-bottom:12px}
/* R55: the meta row is gone from lesson courses, so the title now sits
   directly above the price. It carries the row's bottom margin instead —
   without this the card keeps a 12px hole where the line used to be. */
.cc-title-last{margin-bottom:13px}
.cc-foot{display:flex;align-items:center;justify-content:space-between}
.cc-price{font-family:var(--fm);font-size:17px;font-weight:700}
.rail-fade{position:absolute;top:56px;bottom:0;width:56px;pointer-events:none;z-index:2}
.rail-fade.r{right:-2px;background:linear-gradient(to left,var(--paper),transparent)}
.rail-fade.l{left:-2px;background:linear-gradient(to right,var(--paper),transparent);opacity:0}

/* ===== Sections ===== */
.sect{padding:64px 5%;max-width:1400px;margin:0 auto}
.sect-head{text-align:center;max-width:640px;margin:0 auto 40px}
.sect-title{font-size:clamp(24px,2.8vw,34px);font-weight:600;margin:10px 0 12px}
.sect-sub{font-size:14.5px;color:var(--text2);line-height:1.65}

/* Task #26: .dept-grid/.dtile rules removed — the Departments section that
   used them is gone from this page. Left the JS hydrator that built them
   alone (see Task #26 comment near the old section) since it's inert now,
   not broken; these CSS rules had no such reason to stay. */

.steps{display:grid;grid-template-columns:1fr;gap:16px;position:relative}
@media(min-width:860px){.steps{grid-template-columns:repeat(3,1fr)}}
.step{padding:26px;text-align:center;position:relative}
.step-num{width:44px;height:44px;border-radius:var(--r-obj);margin:0 auto 16px;display:flex;align-items:center;justify-content:center;font-family:var(--fm);font-size:17px;font-weight:500;color:var(--brand-on);background:var(--brand)}
.step h3{font-size:16px;font-weight:600;margin-bottom:8px}
.step p{font-size:13px;color:var(--text2);line-height:1.6}
.step-dots{display:none}
@media(min-width:860px){.step-dots{display:block;position:absolute;top:50px;height:3px;width:8%;background-image:radial-gradient(var(--text3) 1.3px,transparent 1.5px);background-size:10px 3px;opacity:.5}}
.sd1{left:31%}.sd2{left:64.5%}

/* R145 — owner: "the arrangement of the home page is very bad." One
   concrete, screenshotted cause: both grids below used a fixed
   repeat(N,1fr) column count at desktop width. .feat-grid has exactly 5
   cards (hand-authored, not data-driven) — repeat(3,1fr) gave a 3-over-2
   layout with the second row's two cards left-aligned under an empty gap
   where a third card should be. .tutor-grid is populated at runtime from
   however many real tutors exist (repeat(4,1fr)) — with the owner's real
   2 tutors that meant two cards taking the left half of the row and blank
   white space filling the other half, which reads as broken content, not
   a deliberate layout.
   Both switch to flex-wrap + justify-content:center at the same ≥860px
   breakpoint: cards grow up to a max width and wrap onto as many columns
   as actually fit, and — the part that fixes both screenshots — an
   incomplete last row centers itself instead of hanging left with a gap.
   This also means .tutor-grid no longer needs to know the tutor count in
   advance; 1 tutor, 2, or 12 all lay out cleanly. Mobile (<860px) keeps
   its existing 2-column grid untouched — that tier wasn't part of the
   report. */
.feat-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
@media(min-width:860px){
  .feat-grid{display:flex;flex-wrap:wrap;justify-content:center;gap:16px}
  .feat{flex:1 1 220px;max-width:260px}
}
.feat{padding:22px}
.feat .fi{font-size:24px;margin-bottom:12px}
.feat h3{font-size:14.5px;font-weight:600;margin-bottom:6px}
.feat p{font-size:12.5px;color:var(--text2);line-height:1.6}

/* Task #27: .tutor-grid/.tutor rules removed along with the "Your tutors"
   section that used them. The JS hydrator stays (see Task #27 comment near
   the old section) — it's inert now, not broken; these CSS rules had no
   such reason to stay. */

/* R163 (revised) — owner: "bring back card/panel treatment" for both the
   closing CTA band and the download section below, THEN: "it is a fresh
   decision because i wanted its style to be nice like the founder card" —
   so a plain .glass box was the wrong reading of that ask. Both now share
   the exact same offset-gradient-plate treatment as .fq-outer/.fq (the
   biorender-referenced founder card, see that CSS comment) via the generic
   .bio-plate wrapper below, instead of each hand-rolling its own copy of
   the same three rules. */
.bio-plate{position:relative}
.bio-plate::before{content:'';position:absolute;top:16px;left:16px;right:-16px;bottom:-16px;border-radius:30px;background:linear-gradient(135deg,var(--brand-soft) 0%,var(--accent-soft) 100%);z-index:0}
@media(max-width:520px){.bio-plate::before{top:10px;left:10px;right:-10px;bottom:-10px}}

.cta-band{margin:0 5% 64px;padding:0;text-align:center;overflow:hidden}
@media(min-width:1500px){.cta-band{max-width:1400px;margin:0 auto 64px}}
.cta-outer{max-width:640px;margin:0 auto}
.cta-card{position:relative;z-index:1;padding:48px 40px;border:1.5px solid var(--brand-soft);border-radius:24px;background:var(--surface);box-shadow:var(--shadow)}
.cta-band h2{font-size:clamp(24px,3vw,36px);font-weight:600;margin-bottom:12px}
/* R166 — owner: "i wanted to change the font of Your seniors memorized it
   the hard way... Join students studying smarter..." The h2 already used
   --fd (Space Grotesk, same as every other heading on the page — h1-h4's
   base rule) but this paragraph, like every other page's plain <p>, was
   inheriting body's --fb (Source Sans 3) instead — two different typefaces
   in one small, closing CTA block. Matching it to --fd gives the whole
   block one voice, same family as the founder-quote card above it. */
.cta-band p{font-size:14.5px;color:var(--text2);margin-bottom:26px;font-family:var(--fd)}
@media(max-width:520px){.cta-card{padding:36px 24px}}

/* R147: .foot / .foot-bottom moved to assets/app.css §21 — same reasoning
   as the nav above. Edit them there, not here. */
/* R36 (owner feedback #4): scroll-triggered reveal. Elements are tagged .rv
   FROM SCRIPT (the markup stays clean), start slightly lowered + transparent,
   and ease in when they enter the viewport; a per-row transition-delay gives
   the graded stagger. No-JS visitors, browsers without IntersectionObserver
   and prefers-reduced-motion users are never gated: the class is simply never
   applied (or neutralised), so everything is visible immediately. */
.rv{opacity:0;transform:translateY(26px);transition:opacity .65s cubic-bezier(.16,.68,.3,1),transform .65s cubic-bezier(.16,.68,.3,1)}
.rv.rv-in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.rv{opacity:1;transform:none;transition:none}}

/* Task #29 — owner: "this whole design is very bad, too much words to
   install the app, and the mock photo is really bad." Replaces Task #28's
   phone-mockup + badge-row + paragraph entirely.

   assets/screenshot-dashboard.png and the .hero-shot/.hero-shot-phone/
   .dev-badge rules that drew the old phone mockup and branded badge row are
   gone from this page — nothing else references them (install-app.html has
   always drawn its own separate .device-mock illustration from
   assets/app.css §19c, untouched by any of this).

   In their place: icons/icon-512.png is the literal PNG the manifest ships
   as the installed home-screen icon (verified: manifest.webmanifest's
   "any"-purpose 512 entry), shown large with nothing else competing for
   attention. filter:drop-shadow (not box-shadow) is used deliberately —
   the PNG's corners are real alpha transparency (a rounded-square icon
   already baked in, confirmed by sampling corner pixels), and box-shadow
   would draw a square shadow behind that round shape while drop-shadow
   follows the actual silhouette. */
.getapp-outer{max-width:440px;margin:0 auto}
.getapp-card{position:relative;z-index:1;padding:40px 32px 36px;border:1.5px solid var(--brand-soft);border-radius:24px;background:var(--surface);box-shadow:var(--shadow);text-align:center}
.getapp-head{font-size:19px;font-weight:700;margin:4px 0 8px}
.getapp-sub{font-size:13.5px;color:var(--text2);line-height:1.55;margin:0 0 16px}
/* R169 — owner: "show it as a carousel like what we will do for the
   questions and notes and flashcards" — the get-app card's feature line
   (.getapp-sub above, kept in full for anyone without JS and for screen
   readers) gets a small decorative crossfade underneath it cycling through
   the same six real features one at a time with their own icon, reusing
   the exact .fq-ic icon markup/colors from the "Why Memorize" list above
   rather than inventing new glyphs — aria-hidden, purely visual, same
   ambient/no-controls convention as ldemoRun() and feedbackCarousel(). */
.getapp-feat{display:flex;align-items:center;justify-content:center;gap:10px;margin:0 0 14px}
.getapp-feat-ic{width:32px;height:32px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex:none;transition:background .3s ease,color .3s ease}
.getapp-feat-ic .ic{width:17px;height:17px}
.getapp-feat-txt{font-size:13.5px;font-weight:600;transition:opacity .25s ease}
.getapp-feat-dots{display:flex;gap:6px;justify-content:center;margin:0 0 24px}
.getapp-feat-dot{width:6px;height:6px;border-radius:50%;background:var(--line);transition:background .3s ease}
.getapp-feat-dot.is-on{background:var(--brand)}
@media(prefers-reduced-motion:reduce){.getapp-feat-ic,.getapp-feat-txt,.getapp-feat-dot{transition:none}}
.getapp-icon-wrap{position:relative;display:flex;justify-content:center;margin:0 auto 24px}
.getapp-icon-wrap::before{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:170px;height:170px;background:radial-gradient(closest-side,var(--edge-brand),transparent);filter:blur(30px);opacity:.8;z-index:0}
.getapp-icon{position:relative;z-index:1;width:96px;height:96px;display:block;filter:drop-shadow(0 16px 28px rgba(20,25,32,.35))}
@media(max-width:520px){.getapp-card{padding:32px 22px 28px}}

/* Task #31 — icon-only install button, homepage only. The shared component
   (app.js §7I) always renders icon + a text <span> (reads "Install" as of
   Task #52's label shortening); that text stays in the DOM (screen-reader/
   keyboard name) and is only visually clipped — the standard sr-only
   technique, not display:none, which VoiceOver/NVDA would also treat as no
   name at all. */
.getapp-install-wrap{position:relative;display:inline-flex}
.getapp-install-compact .install-btn{width:60px;height:60px;padding:0;border-radius:50%;justify-content:center;background:var(--brand);border-color:var(--brand);color:var(--brand-on)}
.getapp-install-compact .install-btn:hover{background:var(--brand-ink);border-color:var(--brand-ink);color:var(--brand-on)}
.getapp-install-compact .install-btn .ic{width:24px;height:24px;visibility:hidden}
.getapp-install-compact .install-btn span{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.getapp-install-icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:24px;height:24px;color:var(--brand-on);pointer-events:none}

/* ===== Task #24 — "How it works" + "Why Memorize" cards, referencing
   BioRender's feature-card block (solid color header block + icon, thin
   accent line, plain body below) — only the card STRUCTURE is taken from
   the reference; colors are Memorize's own existing brand tokens (the
   same tokens .btn-primary/.btn-accent already use for text-on-solid),
   no photography/illustration is borrowed, copy is untouched. */
.step,.feat{padding:0;overflow:hidden;text-align:left}
.step{text-align:center}
.step-top,.feat-top{height:96px;display:flex;align-items:center;justify-content:center;position:relative}
.step-top .ic{width:30px;height:30px}
.feat-top .ic{width:26px;height:26px}
.step-num{position:absolute;top:10px;right:10px;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-family:var(--fm);font-size:11px;font-weight:600;background:rgba(255,255,255,.24)}
.step-accent,.feat-accent{height:3px}
.step-body{padding:22px 26px}
.feat-body{padding:18px 20px}
.step-body h3{margin-bottom:8px}
.feat-body h3{margin-bottom:6px}

.step.c1 .step-top,.step.c1 .step-accent{background:var(--brand)}
.step.c1 .step-top .ic{color:var(--brand-on)}
.step.c2 .step-top,.step.c2 .step-accent{background:var(--accent)}
.step.c2 .step-top .ic{color:var(--accent-on)}
.step.c3 .step-top,.step.c3 .step-accent{background:var(--jade)}
.step.c3 .step-top .ic{color:var(--jade-on)}

.feat:nth-of-type(5n+1) .feat-top,.feat:nth-of-type(5n+1) .feat-accent{background:var(--brand)}
.feat:nth-of-type(5n+1) .feat-top .ic{color:var(--brand-on)}
.feat:nth-of-type(5n+2) .feat-top,.feat:nth-of-type(5n+2) .feat-accent{background:var(--accent)}
.feat:nth-of-type(5n+2) .feat-top .ic{color:var(--accent-on)}
.feat:nth-of-type(5n+3) .feat-top,.feat:nth-of-type(5n+3) .feat-accent{background:var(--jade)}
.feat:nth-of-type(5n+3) .feat-top .ic{color:var(--jade-on)}
.feat:nth-of-type(5n+4) .feat-top,.feat:nth-of-type(5n+4) .feat-accent{background:var(--crimson)}
.feat:nth-of-type(5n+4) .feat-top .ic{color:var(--crimson-on)}
.feat:nth-of-type(5n+5) .feat-top,.feat:nth-of-type(5n+5) .feat-accent{background:var(--brand)}
.feat:nth-of-type(5n+5) .feat-top .ic{color:var(--brand-on)}

/* ===== Task #25 — founder quote card, referencing BioRender's testimonial
   module structure (offset color plate behind a bordered white quote card,
   avatar + name/title row). This is a REAL quote and photo the owner
   supplied for themselves — not a fabricated testimonial — so it does not
   fall under this repo's ban on invented reviews/trust content. */
/* R162 — owner: "I needed the feedback card and the founder card styles to
   be like what is in biorender." Opened biorender.com and looked at their
   own testimonial cards directly (two of them, on the homepage) rather than
   guessing from the old Task #25/#43 comments' memory of it: each one is a
   soft two-tone gradient plate, offset behind-and-below a bordered white
   card; the quote is plain typographic quotation marks with ONE phrase
   bolded in brand blue — no decorative giant quote-mark glyph anywhere; and
   the attribution row is a circular photo + bold name + a gray role line
   underneath. Task #43 (this repo, an earlier round) had deliberately
   REMOVED an offset-plate treatment for looking "dated" next to the rest of
   the page — that direction is reversed here on the owner's own explicit,
   specific reference, not casually re-litigated: BioRender's actual current
   site still uses exactly that plate today, screenshotted just now, so this
   is matching a real live reference, not undoing a past decision on a whim.
   R161's giant background quote-mark glyph (.fq-markbig/.fcv-mark) is
   removed for the same reason — biorender has no such glyph, just plain
   "…" characters as part of the quote text itself. */
.fq-outer{position:relative;max-width:640px;margin:0 auto}
.fq-outer::before{content:'';position:absolute;top:16px;left:16px;right:-16px;bottom:-16px;border-radius:30px;background:linear-gradient(135deg,var(--brand-soft) 0%,var(--accent-soft) 100%);z-index:0}
.fq{position:relative;z-index:1;padding:40px 44px 36px;border:1.5px solid var(--brand-soft);border-radius:24px;background:var(--surface);box-shadow:var(--shadow)}
/* v196: .fq-tag-row/.fq-tag removed with the label they styled. */
.fq-quote{font-size:17px;line-height:1.75;color:var(--text);margin:0;font-family:var(--fd);font-weight:500}
.fq-hl{color:var(--brand-ink);font-weight:700}
.fq-who{display:flex;align-items:center;gap:14px;margin-top:24px;padding-top:20px;border-top:1px solid var(--line)}
.fq-avatar-wrap{width:52px;height:52px;border-radius:50%;flex:none;display:flex}
.fq-avatar{width:100%;height:100%;border-radius:50%;object-fit:cover;flex:none;display:block}
.fq-name{display:flex;flex-direction:column;font-size:13.5px;line-height:1.45}
.fq-name b{font-weight:700;color:var(--text)}
.fq-name span{color:var(--text2);font-size:12px;font-weight:500}
@media(max-width:520px){.fq{padding:30px 24px 26px}.fq-outer::before{top:10px;left:10px;right:-10px;bottom:-10px}}

/* R157 (task C3) — student feedback carousel, directly under the founder
   quote card. Approved-only (RLS narrows Memorize.api.publicFeedback() to
   status='approved' rows, and the moderation queue in admin.html is the
   only way a row gets there), auto-rotating "as if live" per the owner's
   own wording — one card visible at a time, a soft crossfade, no manual
   controls to keep it feeling ambient rather than like a widget. Hidden
   entirely (not even the shell) when there is nothing approved yet, so an
   empty state never sits under the founder's real quote looking unfinished. */
/* R162 — same biorender reference as .fq above, scaled down: an offset
   gradient plate behind a bordered white card, plain quote marks (no glyph
   icon), photo + bold name + a gray line underneath (course, standing in
   for biorender's job-title line). Avatar still uses the "initials base
   layer, real photo overlaid on top, removes itself on error" convention
   app.js already uses for the public tutor grid (search
   "data-onerror=\"this.remove()\"" in this file) — most students never set a
   profile photo, so this must degrade gracefully, not show a broken image. */
.fcv{display:none;max-width:640px;margin:22px auto 0;position:relative}
.fcv.is-live{display:block}
/* v196 — owner: "the feedbacks that show in home page to take the same style"
   as the printable card the admin now saves for each piece of feedback. So the
   same card: white, a hairline border, the quote large and set in the display
   face, a rule, then the initials disc, the name and the course. The offset
   colour plate is replaced by the printable card's own corner wash, drawn
   inside the card, so the two read as the same object in two places. */
.fcv::before{content:none}
.fcv-card{position:relative;z-index:1;overflow:hidden;padding:30px 32px 24px;
  border:1px solid var(--line);border-radius:22px;background:var(--surface);box-shadow:var(--shadow)}
.fcv-card::after{content:'';position:absolute;right:0;bottom:0;width:62%;height:58%;pointer-events:none;
  background:linear-gradient(135deg,transparent 0 49.6%,var(--brand-soft) 50%,var(--paper) 100%)}
.fcv-quote{position:relative;z-index:1;font-size:19px;line-height:1.55;letter-spacing:-.01em;font-weight:600;
  color:var(--text);margin:0;font-family:var(--fd)}
.fcv-who{position:relative;z-index:1;display:flex;align-items:center;gap:14px;margin-top:22px;padding-top:18px;
  border-top:1px solid var(--line)}
.fcv-avatar-wrap{position:relative;width:46px;height:46px;border-radius:50%;background:var(--brand-soft);flex:none;display:flex;align-items:center;justify-content:center}
.fcv-avatar-ini{font-size:15px;font-weight:700;color:var(--brand-ink)}
.fcv-avatar{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;object-fit:cover;display:none}
.fcv-namewrap{display:flex;flex-direction:column;font-size:15px;line-height:1.4}
.fcv-name{font-weight:700;color:var(--text)}
.fcv-course{color:var(--text3);font-size:13px;font-weight:500}
.fcv-dots{position:relative;z-index:1;display:flex;gap:6px;justify-content:center;margin-top:12px}
.fcv-dot{width:6px;height:6px;border-radius:50%;background:var(--line);transition:background .3s ease}
.fcv-dot.is-on{background:var(--brand)}

/* R163 — owner: "a real content flow like biorender, for example a
   question, notes thing while being added, flashcard being studied." Same
   idea as BioRender's own animated hero mockup (a tiny "app window" that
   plays out a short, looping, fully autonomous demo — nothing here is a
   real flashcard/quiz/note, it's a mock UI performing a scripted sequence
   purely to SHOW what studying with Memorize looks like) — placed in the
   gap between the feature list and the download section, per the owner's
   own answer on where this should live. ldemoRun() below drives one state
   machine through three scenes (flashcard flip, quiz answer, note taken
   from that same quiz question — the owner specifically asked for the note
   to come from the quiz, not a separate lecture-notes scene), looping
   forever; prefers-reduced-motion gets the first scene only, frozen, same
   convention as the boot-loader pulse and the founder-card carousel. */
/* R170 — owner (verbatim): "i need those features to flow in a carousel
   each one should have their carousel ,the q bank,the flashcards,the
   studyplanner ,the printable notes ,the notes itself ,need the same thing
   that you saw with the complete mockup !!!!!!!!!!!!!!!!!!!!!!!!! refrence
   for their style is biorender". Replaces the single shared ldemoRun() card
   (3 scenes cycling in ONE .ldemo-card via showScene()) with independent,
   self-contained looping cards — QBank, Flashcards, Study Planner,
   Printable Notes, Notes & memorize, and (R171) OSCE stations — each
   driven by its own runner in ldemoCarousels() below, none of them
   scene-switching into a shared shell. The outer wrapper is a responsive
   grid of cards.

   R171 — owner: "your reference for the things you did in the carousels we
   just added was biorender, it's right but wanted you to make what you
   made to be our brand design." .ldemo-card's shape (rounded-rect, hairline
   border, soft shadow — .glass's own object language, assets/app.css §6)
   and .ldemo-body/.ldemo-scene are UNCHANGED — that shape was never the
   generic part. Only the chrome BAR is restyled here, with pieces already
   established elsewhere on this exact page rather than invented fresh:
     - the bar's background is the same soft diagonal brand-to-accent
       plate used behind .bio-plate/.fq-outer/.fcv (this file, R-various)
       — here in miniature and flattened onto the bar itself, not offset
       behind it, so it reads as a texture the chrome sits on rather than
       a card-editor drop shadow;
     - the three chrome dots now carry the site's own three-way accent
       rotation (brand/accent/jade — the exact same trio .step.c1/.c2/.c3
       and .feat:nth-of-type(5n+2)/(5n+3) already use throughout this page)
       instead of the generic macOS red/yellow/green traffic-light dots;
     - the real logo mark (.lock-mark/.logo-d/.logo-l, canvas.css) sits in
       the bar at a small size, light/dark-swapped exactly as the header
       lockup does — so the chrome is legibly THIS product's window, not a
       generic "app mockup" convention.
   Applied uniformly to all six cards; no change to any card's internal
   scene content, timing or data. */
.ldemo-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:20px;max-width:1180px;margin:0 auto}
@media(max-width:680px){.ldemo-grid{grid-template-columns:1fr;max-width:440px}}
.ldemo-card{position:relative;border:1px solid var(--line);border-radius:20px;background:var(--surface);box-shadow:var(--shadow);overflow:hidden;display:flex;flex-direction:column}
.ldemo-bar{display:flex;align-items:center;gap:8px;padding:11px 16px;border-bottom:1px solid var(--line);background:linear-gradient(120deg,var(--brand-soft) 0%,var(--surface-2) 65%)}
.ldemo-bar-mark{width:16px;height:14px;flex:none;position:relative;opacity:.9}
.ldemo-bar-mark img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.ldemo-dotc{width:8px;height:8px;border-radius:50%;flex:none}
.ldemo-dotc-1{background:var(--brand)}
.ldemo-dotc-2{background:var(--accent)}
.ldemo-dotc-3{background:var(--jade)}
.ldemo-bar-label{margin-left:4px;font-size:11px;font-weight:700;color:var(--text3);letter-spacing:.04em;text-transform:uppercase}
.ldemo-body{padding:22px 20px;min-height:250px;flex:1}
/* R176: fixed floor so scene changes never resize the cards (and never push
   the sections below). Sized to the tallest state of each card; the JS
   ldemoHoldHeight() ratchet covers widths or data these do not. */
@media(min-width:681px){.ldemo-body{min-height:640px}}
@media(max-width:680px){
  .ldemo-grid>.ldemo-card:nth-child(1) .ldemo-body{min-height:620px}
  .ldemo-grid>.ldemo-card:nth-child(2) .ldemo-body{min-height:320px}
  .ldemo-grid>.ldemo-card:nth-child(3) .ldemo-body{min-height:620px}
  .ldemo-grid>.ldemo-card:nth-child(4) .ldemo-body{min-height:500px}
  .ldemo-grid>.ldemo-card:nth-child(5) .ldemo-body{min-height:570px}
  .ldemo-grid>.ldemo-card:nth-child(6) .ldemo-body{min-height:440px}
}
.ldemo-scene{width:100%}
.ldemo-flash{border:1.5px solid var(--line);border-radius:var(--r-obj);padding:26px 18px;text-align:center;min-height:104px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px}
.ldemo-flash-tag{font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text3)}
.ldemo-flash-txt{font-size:15px;font-weight:600;color:var(--text)}
/* R171 — new 6th card: OSCE stations. Owner-supplied real clinical cases
   (Cullen's/Grey-Turner's signs in acute pancreatitis; chronic venous
   insufficiency signs), OSCE "spot diagnosis" format — a photo + vignette,
   revealing to the sign/diagnosis + a brief note. Reuses the Flashcards
   card's exact front/back mechanic (.ldemo-flash-tag/.ldemo-flash-txt,
   progress bar, opacity/transform reveal) rather than inventing a new one;
   only the image + its post-reveal caption are new. The image sits above
   the text panel and stays in place across the reveal — only the caption
   and text panel change — and again across the case swap, so the card
   never feels like it replaces the whole scene. Fixed image height (not
   aspect-ratio) because the two source photos have different aspect
   ratios; object-fit:cover crops rather than distorting either one. */
.ldemo-osce-img-wrap{position:relative;border-radius:var(--r-obj);overflow:hidden;height:132px;background:var(--surface-2)}
.ldemo-osce-img{width:100%;height:100%;object-fit:cover;display:block}
.ldemo-osce-cap{position:absolute;left:0;right:0;bottom:0;padding:6px 10px;font-size:11px;font-weight:700;color:#fff;background:linear-gradient(0deg,rgba(0,0,0,.62),transparent);opacity:0;transform:translateY(4px);transition:opacity .3s ease,transform .3s ease}
.ldemo-osce-cap.is-in{opacity:1;transform:none}
.ldemo-osce{display:flex;flex-direction:column;gap:12px}
.ldemo-osce-panel{border:1.5px solid var(--line);border-radius:var(--r-obj);padding:14px 16px;display:flex;flex-direction:column;gap:6px;transition:background .3s ease,border-color .3s ease}
.ldemo-osce-panel.is-answer{background:var(--jade-soft);border-color:var(--jade)}
.ldemo-osce-txt{font-size:13px;line-height:1.5;color:var(--text);text-align:left}
/* R166 — owner: "not the same shape and style which will lead to
   misunderstanding." This whole scene used to be an invented mock UI (see
   the R163 comment above) — filled pill chips for the grade buttons, a
   2-column box grid for quiz options — that never matched what the real
   product actually looks like, which is exactly backwards once the content
   itself became real (R165/166): a real question deserves the real chrome
   around it, or a prospective student learns the wrong shape. Below now
   mirrors the ACTUAL components verbatim: flashcards.html's .gbtn/.g1/.g3/
   .g4 grade buttons (bordered box, tinted border only, label + time hint —
   never a filled pill), and quiz.html's .opt/.opt-key/.opt-txt row list
   (lettered circle + full-width row + bottom-border separator, never a
   bordered box grid). Colors/radii are the same tokens those pages use,
   not approximations. */
.ldemo-srs{display:flex;gap:8px;margin-top:10px;width:100%;opacity:0;transform:translateY(6px);transition:opacity .3s ease,transform .3s ease}
.ldemo-srs.is-in{opacity:1;transform:none}
.ldemo-srs .ld-btn{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 4px;border-radius:var(--r-obj);border:1px solid var(--line);background:var(--surface)}
.ldemo-srs .ld-btn b{font-size:12px;font-weight:600}
.ldemo-srs .ld-btn span{font-family:var(--fm);font-size:10px;color:var(--text3)}
.ldemo-srs .ld-again{border-color:rgba(232,106,98,.4)}
.ldemo-srs .ld-again b{color:var(--danger)}
/* R168 — owner: "same thing for the flashcards." flashcards.html's real
   study screen always shows all FOUR grade buttons (.g1 Again/.g2 Hard/.g3
   Good/.g4 Easy) plus its own .progress bar above the card — this scene
   previously dropped Hard and had no progress bar at all. .ld-hard mirrors
   .g2's exact orange tint verbatim. */
.ldemo-srs .ld-hard{border-color:rgba(231,135,43,.4)}
.ldemo-srs .ld-hard b{color:var(--orange-hi)}
.ldemo-srs .ld-good{border-color:rgba(90,170,70,.4)}
.ldemo-srs .ld-good b{color:var(--green-hi)}
.ldemo-srs .ld-easy{border-color:rgba(49,126,194,.4)}
.ldemo-srs .ld-easy b{color:var(--blue-hi)}
/* R170 — owner asked the flashcard scene show the grading interaction, not
   just reveal and stop: a brief press-state on "Good" (flashcards.html's
   real .gbtn:active/.g3 tint, held a moment longer here so an autoplay
   viewer can actually see it). */
.ldemo-srs .ld-good.is-pressed{background:var(--jade-soft);border-color:var(--jade)}
/* R168 — owner: "they do not really show the real style with the bars and
   explanations per choice or the explanation under it and select to
   highlight OR TO Memorize and the full visual style of it that lives
   inside the app." Four real pieces of chrome added to the quiz scene,
   matching quiz.html verbatim: (1) the TYPE badge (quiz.html's
   TYPE.multiple_choice → ['Single best answer','bg-blue'] — reusing the
   real site-wide .badge/.bg-blue classes from assets/app.css directly,
   not a re-invented lookalike, since every row this demo can ever show is
   flagged multiple_choice by MIGRATION-r165's own SQL filter); (2) a thin
   .progress-style fill bar next to it ("the bars"); (3) the main .explain
   panel below the options, using quiz.html's own hardcoded hex values
   (#2B5C93/#DCE8F5/#1D2126/#1E4570 — see quiz.html's R106/R107 comment for
   why those never follow the theme). Per-choice explanations
   (Q.choiceEx[i], quiz.html's .opt-explain) are NOT reproduced here: the
   demo's only data source, Memorize.api.publicDemoSample(), returns one
   combined `explanation` string per MIGRATION-r165's design (a per-choice
   breakdown would need new question_pool columns and a fresh SQL
   migration) — a deliberate, disclosed scope line, not an oversight. */
.ldemo-q-top{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.ldemo-q-progress{flex:1;height:3px;border-radius:2px;background:var(--line);overflow:hidden}
.ldemo-q-progress-fill{display:block;height:100%;width:0;background:var(--brand);transition:width .5s ease}
.ldemo-q-stem{font-size:13.5px;font-weight:600;margin-bottom:10px;text-align:left}
.ldemo-q-list{display:flex;flex-direction:column}
.ldemo-opt{display:flex;align-items:center;gap:12px;padding:9px 2px;border-bottom:1px solid var(--line);transition:background .3s ease}
.ldemo-opt:last-child{border-bottom:none}
.ldemo-opt-key{width:22px;height:22px;flex:none;border-radius:50%;border:1.5px solid var(--line);display:flex;align-items:center;justify-content:center;font-size:10.5px;font-weight:700;font-family:var(--fb);transition:background .3s ease,border-color .3s ease,color .3s ease}
.ldemo-opt-txt{flex:1;font-size:12.5px;text-align:left}
.ldemo-opt.is-correct{background:var(--jade-soft)}
.ldemo-opt.is-correct .ldemo-opt-key{background:var(--jade);border-color:var(--jade);color:var(--jade-on)}
/* R169 — owner, after actually opening the real student account and
   working through a live MRCS question: "the strike out to exclude wrong
   answers before answering anything" + "if pressed a wrong answer it will
   show a recall cue, if right answer it wont show it." Confirmed live on
   quiz.html: tapping an option's TEXT strikes it out (a plain gray
   elimination, no color, done before committing to an answer); tapping the
   lettered CIRCLE is what actually submits that option as your answer —
   wrong turns the row/circle crimson and opens a RECALL CUE box (which
   then stays open even once you get it right on a later attempt); correct
   turns the row/circle jade and opens no recall cue at all. This demo is a
   non-interactive autoplay loop (nobody is really clicking), so it scripts
   that exact sequence instead: strike a distractor, "tap" a second wrong
   option (recall cue opens), then "tap" the real correct option (recall
   cue stays, correct option turns jade, .explain panel opens) — the same
   order a real student misreading the stem would actually see. */
.ldemo-opt.is-struck .ldemo-opt-txt{opacity:.55;text-decoration:line-through}
.ldemo-opt.is-wrong{background:var(--crimson-soft)}
.ldemo-opt.is-wrong .ldemo-opt-key{background:var(--crimson);border-color:var(--crimson);color:#fff}
.ldemo-opt.is-wrong .ldemo-opt-txt{text-decoration:line-through}
.ldemo-recall{margin-top:12px;padding:0 15px;border-radius:var(--r-obj);border:1px solid transparent;background:#DCE8F5;color:#1D2126;font-size:11.5px;line-height:1.55;text-align:left;opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .35s ease,padding .35s ease,border-color .35s ease}
.ldemo-recall.is-in{opacity:1;max-height:70px;padding:10px 15px;border-color:#2B5C93}
.ldemo-recall-eyebrow{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#1E4570;margin-bottom:3px}
/* Main explanation panel — quiz.html's .explain/.explain-eyebrow verbatim,
   including the deliberately hardcoded (non-theme) colors. */
.ldemo-explain{margin-top:14px;padding:0 15px;border-radius:var(--r-obj);border:1px solid transparent;background:#DCE8F5;color:#1D2126;font-size:12px;line-height:1.62;text-align:left;opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .35s ease,padding .35s ease,border-color .35s ease}
.ldemo-explain.is-in{opacity:1;max-height:150px;padding:13px 15px;border-color:#2B5C93}
.ldemo-explain-eyebrow{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#1E4570;margin-bottom:4px}
.ldemo-note-stem{font-size:12px;color:var(--text3);margin-bottom:12px;padding-bottom:12px;border-bottom:1px dashed var(--line);text-align:left}
/* R168 — the Notes scene used to be an invented "+ Add note chip -> plain
   box" mock. Replaced with a mock of the REAL mechanic (quiz.html's
   qnBubble): a passage of the explanation text, a simulated text
   selection, a small floating pill toolbar with a highlight-color dot plus
   "Highlight"/"Memorize" buttons (quiz.html's own #qnAdd/#qnAddNote — R112:
   the product's own name used as the verb "for keeping something"), then
   the passage settling into a permanent yellow <mark>-style highlight —
   same rgba(255,209,0,.55) quiz.html's real .qn-hl uses. Kept as a normal
   flow element (fades/collapses like the old chip/box did) rather than a
   truly floating absolutely-positioned bubble, so it can never be clipped
   by .ldemo-card's overflow:hidden. */
.ldemo-note-passage{font-size:12.5px;line-height:1.65;color:var(--text2);text-align:left}
.ldemo-note-passage .is-selected{background:rgba(49,126,194,.28);border-radius:3px}
.ldemo-note-passage .is-hl{background:rgba(255,209,0,.55);border-radius:3px}
.ldemo-qnbubble{display:inline-flex;align-items:center;gap:8px;margin-top:0;background:#1c2430;color:#fff;padding:0 12px;border-radius:999px;box-shadow:0 6px 16px rgba(0,0,0,.2);opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .35s ease,padding .35s ease,margin-top .35s ease}
.ldemo-qnbubble.is-in{opacity:1;max-height:34px;padding:7px 12px;margin-top:12px}
.ldemo-qnbubble-dot{width:11px;height:11px;flex:none;border-radius:50%;background:rgba(255,209,0,.9)}
.ldemo-qnbubble-btn{font-size:11px;font-weight:700;color:#fff;white-space:nowrap}
.ldemo-qnbubble-btn-ghost{color:rgba(255,255,255,.75)}
.ldemo-qnbubble-sep{width:1px;height:13px;flex:none;background:rgba(255,255,255,.25)}
/* R170 — Study Planner scene: mirrors student.html's real #panel-planner
   chrome verbatim (spMastheadHtml/spTodayHtml/spPanelTabsHtml, student.html
   ~lines 3232-3253 and 3688-3790) — eyebrow (compass + course/day line),
   an h1-weight module name with an exam-countdown chip beside it, a thin
   rule, a "Today's session" card (dot-label, module/lesson name, summary
   line, a primary "Start today's questions" + ghost "Start today's
   lecture" CTA pair), then the pill/folder tab row (This week / Course
   shape / Study order / Settings) with a soft color wash on the active
   tab — never invented shapes, the same tokens the rest of this file uses. */
.ldp-eyebrow{display:flex;align-items:center;gap:6px;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text3);margin-bottom:6px}
.ldp-eyebrow .ic{width:13px;height:13px;flex:none}
.ldp-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.ldp-module{font-size:15px;font-weight:700;line-height:1.3;text-align:left}
.ldp-chip{flex:none;text-align:center;border:1px solid var(--line);border-radius:var(--r-obj);padding:6px 10px;background:var(--surface-2)}
.ldp-chip b{display:block;font-size:16px;font-weight:800;color:var(--brand)}
.ldp-chip span{display:block;font-size:9px;color:var(--text3);text-transform:uppercase;letter-spacing:.03em;white-space:nowrap}
.ldp-rule{height:1px;background:var(--line);margin:12px 0}
.ldp-grid2{display:grid;grid-template-columns:1fr;gap:10px}
@media(min-width:520px){.ldp-grid2{grid-template-columns:1.3fr 1fr}}
.ldp-session{border:1.5px solid var(--line);border-radius:var(--r-obj);padding:14px;opacity:0;transform:translateY(6px);transition:opacity .3s ease,transform .3s ease}
.ldp-session.is-in{opacity:1;transform:none}
/* R170b — the real Questions/Lectures stat pair + "behind your plan" banner
   (spSummaryHtml(), student.html) that sits beside the Today's-session card
   in the live account — confirmed by opening the real, logged-in planner. */
.ldp-stats{border:1.5px solid var(--line);border-radius:var(--r-obj);padding:14px;opacity:0;transform:translateY(6px);transition:opacity .3s ease,transform .3s ease;display:flex;flex-direction:column;gap:10px}
.ldp-stats.is-in{opacity:1;transform:none}
.ldp-stat-row{display:flex;gap:10px}
.ldp-stat{flex:1;text-align:center}
.ldp-stat-lbl{display:block;font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text3);margin-bottom:2px}
.ldp-stat b{display:block;font-size:17px;font-weight:800;color:var(--brand)}
.ldp-stat b.is-amber{color:var(--orange-hi)}
.ldp-stat-sub{display:block;font-size:9.5px;color:var(--text3)}
.ldp-behind{font-size:10.5px;line-height:1.5;color:var(--crimson);background:var(--crimson-soft);border-radius:var(--r-sm);padding:8px 10px;text-align:left}
.ldp-session-label{display:flex;align-items:center;gap:6px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text3);margin-bottom:6px}
.ldp-session-dot{width:7px;height:7px;border-radius:50%;background:var(--brand);flex:none}
.ldp-session-name{font-size:13.5px;font-weight:700;margin-bottom:4px;text-align:left}
.ldp-session-sum{font-size:11.5px;color:var(--text2);margin-bottom:12px;text-align:left}
.ldp-cta{display:flex;gap:8px;flex-wrap:wrap}
.ldp-cta-primary{font-size:11.5px;font-weight:700;padding:8px 12px;border-radius:var(--r-btn);background:var(--brand);color:var(--brand-on)}
.ldp-cta-ghost{font-size:11.5px;font-weight:700;padding:8px 12px;border-radius:var(--r-btn);border:1px solid var(--line);color:var(--text)}
.ldp-tabs{display:flex;gap:6px;margin-top:12px;flex-wrap:wrap;opacity:0;transform:translateY(6px);transition:opacity .3s ease,transform .3s ease}
.ldp-tabs.is-in{opacity:1;transform:none}
.ldp-tab{font-size:10.5px;font-weight:700;padding:6px 10px;border-radius:999px;color:var(--text3);background:var(--surface-2);white-space:nowrap}
.ldp-tab.is-on{background:var(--brand-soft);color:var(--brand-ink)}

/* R170 — Printable Notes scene: mirrors qbank-notes.html's real ntDraw()
   chrome verbatim — page header (title, "<N> notes · <course>" subtitle,
   search input, "Print / PDF" button), then one note card assembling in:
   module tag, question stem, a green "Correct answer:" line, a
   left-accent "SELECTED PASSAGE" quoted snippet, and a "MY NOTE" box. */
.ldn2-title{font-size:14px;font-weight:700;text-align:left}
.ldn2-sub{font-size:11px;color:var(--text3);margin:2px 0 8px;text-align:left}
.ldn2-search{font-size:11.5px;color:var(--text3);border:1px solid var(--line);border-radius:var(--r-obj);padding:7px 10px;margin-bottom:8px}
.ldn2-print{display:inline-block;font-size:11px;font-weight:700;padding:6px 10px;border-radius:var(--r-btn);border:1px solid var(--line);color:var(--text);transition:background .25s ease,border-color .25s ease}
.ldn2-print.is-pulse{background:var(--brand-soft);border-color:var(--brand)}
.ldn2-card{margin-top:12px;border:1.5px solid var(--line);border-radius:var(--r-obj);padding:12px 14px;text-align:left}
.ldn2-tag{display:inline-block;font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--brand-ink);background:var(--brand-soft);border-radius:999px;padding:2px 8px;margin-bottom:8px}
.ldn2-stem{font-size:12.5px;font-weight:600;opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .3s ease}
.ldn2-stem.is-in{opacity:1;max-height:60px;margin-bottom:8px}
.ldn2-answer{font-size:11.5px;font-weight:600;color:var(--green-hi);opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .3s ease}
.ldn2-answer.is-in{opacity:1;max-height:30px;margin-bottom:8px}
.ldn2-passage-lbl,.ldn2-note-lbl{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text3);margin-bottom:3px}
.ldn2-passage{font-size:11.5px;color:var(--text2);border-left:2px solid var(--brand);padding-left:8px;opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .3s ease}
.ldn2-passage.is-in{opacity:1;max-height:50px;margin-bottom:8px}
.ldn2-note{font-size:11.5px;color:var(--text);opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .3s ease}
.ldn2-note.is-in{opacity:1;max-height:50px}

/* R170 — Notes & memorize scene extension: the existing note-scene classes
   (.ldemo-note-passage/.ldemo-qnbubble) are reused verbatim for the
   select-to-highlight beat; these are the NEW pieces for the note->
   flashcard pipeline confirmed live on student.html's Memorize-notes page —
   the private "kept with this question" note panel, its "Note saved"
   toast, the saved note's "Card" button, and the "Make a flashcard" modal
   preview (editable Front/Back + Save card). */
.ldm-panel{margin-top:12px;border-left:2px solid var(--brand);padding:0 12px;border-radius:0 var(--r-obj) var(--r-obj) 0;background:var(--surface-2);opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .35s ease,padding .35s ease}
.ldm-panel.is-in{opacity:1;max-height:120px;padding:10px 12px}
.ldm-panel-cap{font-size:10px;color:var(--text3);margin-bottom:6px;line-height:1.4}
.ldm-panel-ta{font-size:11.5px;color:var(--text3);border:1px dashed var(--line);border-radius:var(--r-sm);padding:6px 8px}
.ldm-toast{display:inline-block;margin-top:10px;font-size:11px;font-weight:700;color:var(--jade);background:var(--jade-soft);border-radius:999px;padding:5px 12px;opacity:0;transform:translateY(4px);transition:opacity .25s ease,transform .25s ease}
.ldm-toast.is-in{opacity:1;transform:none}
.ldm-chip{display:inline-block;margin-top:10px;font-size:11px;font-weight:700;padding:6px 12px;border-radius:999px;border:1px solid var(--line);color:var(--text);opacity:0;transform:translateY(4px);transition:opacity .25s ease,transform .25s ease}
.ldm-chip.is-in{opacity:1;transform:none}
.ldm-modal{margin-top:10px;border:1.5px solid var(--line);border-radius:var(--r-obj);padding:0 12px;text-align:left;opacity:0;max-height:0;overflow:hidden;transition:opacity .3s ease,max-height .35s ease,padding .35s ease}
.ldm-modal.is-in{opacity:1;max-height:230px;padding:12px}
.ldm-modal-title{font-size:11.5px;font-weight:700;margin-bottom:4px}
.ldm-modal-sub{font-size:10.5px;color:var(--text3);margin-bottom:8px;line-height:1.5}
.ldm-modal-lbl{font-size:9.5px;font-weight:700;text-transform:uppercase;color:var(--text3);margin-bottom:2px}
.ldm-modal-field{font-size:11px;color:var(--text);border:1px solid var(--line);border-radius:var(--r-sm);padding:5px 7px;margin-bottom:6px}
.ldm-modal-save{display:inline-block;font-size:11px;font-weight:700;padding:6px 10px;border-radius:var(--r-btn);background:var(--brand);color:var(--brand-on)}
@media(prefers-reduced-motion:reduce){.ldemo-srs,.ldemo-explain,.ldemo-qnbubble,.ldemo-recall,.ldemo-opt,.ldp-session,.ldp-stats,.ldp-tabs,.ldn2-print,.ldn2-stem,.ldn2-answer,.ldn2-passage,.ldn2-note,.ldm-panel,.ldm-toast,.ldm-chip,.ldm-modal{transition:none}}

/* fq-split — features list beside the quote card, replacing the separate
   "How it works" + "Why Memorize" sections (owner request: put the two
   side by side, drop the standalone steps section). Same real copy as
   before, just relaid out; no content invented. */
.fq-split{display:grid;grid-template-columns:1fr;gap:40px;align-items:center;max-width:1200px;margin:0 auto}
@media(min-width:860px){.fq-split{grid-template-columns:1.05fr 1fr;gap:56px}}
.fq-split-head{font-size:clamp(26px,3vw,38px);font-weight:600;line-height:1.18;margin:10px 0 26px;max-width:440px}
.fq-list{display:flex;flex-direction:column;gap:12px;margin-bottom:28px}
.fq-item{display:flex;align-items:flex-start;gap:14px;border:1px solid var(--line);border-radius:var(--r-obj);padding:14px 16px;background:var(--surface);box-shadow:var(--shadow);transition:border-color .15s}
.fq-item:hover{border-color:var(--text3)}
.fq-ic{width:32px;height:32px;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;flex:none;margin-top:1px}
.fq-ic .ic{width:17px;height:17px}
.fq-ic-1{background:var(--brand-soft);color:var(--brand-ink)}
.fq-ic-2{background:var(--accent-soft);color:var(--accent-ink)}
.fq-ic-3{background:var(--jade-soft);color:var(--jade)}
.fq-ic-4{background:var(--crimson-soft);color:var(--crimson)}
.fq-item b{display:block;font-size:15px;font-weight:600;margin-bottom:3px}
.fq-item p{font-size:13.5px;color:var(--text2);line-height:1.55;margin:0}
.fq-cta{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
.btn-link{display:inline-flex;align-items:center;gap:6px;font-weight:600;font-size:14px;color:var(--brand)}
.btn-link:hover{color:var(--brand-ink);text-decoration:none}
.btn-link span{display:inline-block;transition:transform .15s}
.btn-link:hover span{transform:translateX(3px)}
@media(max-width:859px){.fq-split-head{max-width:100%}.fq-outer{max-width:600px;margin:0 auto}}
