/* ==========================================================================
   app.css — China Match V2 components
   Mobile-first. Layout uses logical properties so the Arabic build mirrors
   without duplicating every rule. Palette comes from css/brand.css.
   ========================================================================== */

.app {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--surface-muted);
}

/* ------------------------------------------------------------------ topbar */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  padding-top: max(8px, env(safe-area-inset-top));
  background: rgba(255, 253, 247, .94);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border-subtle);
  min-height: 56px;
}
.topbar[hidden] { display: none; }

.topbar .brand-mini {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-inline-start: 2px;
  flex: 1;
  min-width: 0;
}
.brand-mini .bm-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--jf-amber);
  flex: 0 0 auto;
}
.brand-mini .bm-word {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 13.5px;
  letter-spacing: -.01em;
  color: var(--brand-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.icon-btn {
  width: var(--tap);
  height: var(--tap);
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 12px;
  background: transparent;
  color: var(--brand-primary);
  cursor: pointer;
  padding: 0;
}
.icon-btn:active { background: var(--surface-tint); }
.icon-btn[disabled] { opacity: .32; pointer-events: none; }

.top-right { display: flex; align-items: center; gap: 2px; }

.progress-wrap { flex: 1; min-width: 0; }
.progress-bar {
  height: 4px;
  border-radius: 99px;
  background: var(--border-subtle);
  overflow: hidden;
}
.progress-bar > span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--jf-orange), var(--jf-amber));
  transition: width .35s var(--ease);
}
.progress-label {
  font-size: 10.5px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------------------------------------------------------------- language */
.lang-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: var(--tap);
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--brand-primary);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.lang-btn .globe { font-size: 14px; line-height: 1; }

.lang-list { display: grid; gap: 6px; }
.lang-option {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 54px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  text-align: start;
  cursor: pointer;
  font-size: 15px;
  color: var(--text-primary);
}
.lang-option.current { border-color: var(--jf-orange); background: var(--surface-tint); }
.lang-option .lo-code {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
  min-width: 24px;
}
.lang-option .lo-name { flex: 1; font-weight: 700; font-size: 14px; }
.lang-option .lo-native { color: var(--text-muted); font-weight: 500; font-size: 12px; }
.lang-option .lo-tick { color: var(--jf-orange); font-weight: 900; }

/* -------------------------------------------------------------------- view */
.view {
  flex: 1;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 14px 16px 32px;
  padding-bottom: max(32px, env(safe-area-inset-bottom));
}
.screen { animation: fade-up .28s var(--ease); }
@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .screen { animation: none; }
  * { scroll-behavior: auto !important; }
}

/* --------------------------------------------------------------- typography */
.eyebrow {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--jf-orange-hover);
}
.title {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.02em;
  margin-top: 6px;
}
.title.sm { font-size: 21px; }
.lead {
  font-size: 14px;
  color: var(--text-secondary);
  margin-top: 8px;
  line-height: 1.5;
}
.muted { color: var(--text-muted); }
.tiny { font-size: 11.5px; line-height: 1.45; }
.strong { font-weight: 700; }

/* ==========================================================================
   HOME
   Five blocks only: brand (logo + wordmark), the two paid plans, the free quiz
   line and three static figures. Hierarchy comes from type scale and whitespace
   instead of a dark hero panel, icons and decorative arcs. Everything sits on
   the light surface with hairline borders; brand navy carries text, orange
   carries the single call to action emphasis. No prices are printed here.
   ========================================================================== */
.hp { padding: 4px 0 0; }

/* --- brand ---------------------------------------------------------------- */
/* Company mark top-left, language switch top-right, product wordmark as text
   underneath. Nothing is set in a heavy panel: the page opens on white. */
.hp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.hp-logo { display: inline-flex; align-items: center; text-decoration: none; }
/* The lockup is a fixed-height image so the header keeps the same height in
   every language; the width follows the 2.17:1 artwork. */
.hp-logo img { display: block; height: 46px; width: auto; }
.hp-lang {
  flex: 0 0 auto;
  min-height: 40px;
  min-width: 58px;
  padding: 0 16px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--brand-primary);
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: .06em;
  cursor: pointer;
  transition: border-color .16s var(--ease), background-color .16s var(--ease);
}
.hp-lang:hover {
  border-color: var(--jf-orange);
  background: #fff8ef;
  color: var(--brand-primary);
}

/* --- hero ----------------------------------------------------------------- */
/* "Match" is the name, "China Scholarship" the secondary line. Type scale and
   whitespace do the work; there is no second slogan under them. */
.hp-hero { padding-top: 18px; }
.hp-wordmark { margin: 0; }
.hp-mark {
  display: block;
  font-size: clamp(42px, 13.5vw, 60px);
  font-weight: 700;
  line-height: .98;
  letter-spacing: -.045em;
  color: var(--brand-primary);
}
.hp-mark-sub {
  display: block;
  margin-top: 9px;
  font-size: clamp(14px, 3.9vw, 16px);
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-secondary);
}
/* Tracking and uppercasing are Latin-script treatments. Arabic loses its
   cursive joins and Thai/Bengali their mark placement under letter-spacing,
   so those three keep the plain setting. */
html[lang="en"] .hp-mark-sub,
html[lang="fr"] .hp-mark-sub,
html[lang="vi"] .hp-mark-sub,
html[lang="ms"] .hp-mark-sub {
  text-transform: uppercase;
  letter-spacing: .14em;
}
html[lang="en"] .hp-free-mark-sub,
html[lang="fr"] .hp-free-mark-sub,
html[lang="vi"] .hp-free-mark-sub,
html[lang="ms"] .hp-free-mark-sub {
  text-transform: uppercase;
  letter-spacing: .1em;
}
.hp-lead {
  margin: 18px 0 0;
  max-width: 34ch;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-secondary);
}

/* --- the two paid plans --------------------------------------------------- */
/* No price on these cards. The amount belongs to the pricing step, which the
   visitor only reaches after telling us what they are looking for. */
.hp-plans { display: grid; gap: 18px; margin-top: 22px; }
.hp-plan {
  position: relative;
  display: block;
  width: 100%;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
  text-align: start;
  cursor: pointer;
  transition: border-color .16s var(--ease);
}
.hp-plan:hover { border-color: var(--border-strong); }
.hp-plan:active { border-color: var(--jf-gold); }
.hp-plan-name {
  display: block;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--brand-primary);
}
.hp-plan-desc {
  display: block;
  margin-top: 7px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text-secondary);
}
/* Premium is emphasised with a warm surface and one accent line rather than a
   second dark panel — a heavy dark card was what made the old page top-heavy. */
.hp-plan--feature {
  border-color: rgba(255, 138, 0, .38);
  background: #fffcf6;
}
.hp-plan-tag {
  position: absolute;
  top: -9px;
  inset-inline-start: 16px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--jf-orange);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}

/* --- free quiz entry ------------------------------------------------------ */
/* Third card, not a footnote. Same border and radius as the paid plans; the
   space where a price would sit carries a large "free" mark instead, so the
   hierarchy is still paid > paid > free but the free option is legible at a
   glance rather than buried in small print. */
.hp-free {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 12px;
}
.hp-free-txt { min-width: 0; }
.hp-free-mark {
  flex: 0 0 auto;
  text-align: center;
  padding-inline-start: 4px;
}
.hp-free-mark-big {
  display: block;
  font-size: 24px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--jf-orange-hover);
}
.hp-free-mark-sub {
  display: block;
  margin-top: 5px;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--text-secondary);
}

/* --- static figures ------------------------------------------------------- */
/* Values live in HOME_FIGURES (app.js) as hand-written copy, not live counts,
   so the page never leaks database size as a queryable statistic. Nothing here
   takes a pointer, a hover state, a chevron or a button role. */
.hp-figures {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.hp-fig-num {
  display: block;
  font-size: clamp(16px, 4.9vw, 22px);
  font-weight: 700;
  letter-spacing: -.03em;
  color: var(--brand-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  /* These are Latin quantities, not Arabic prose. Without an explicit LTR run
     the bidi algorithm reverses them in Arabic: "2025-2027" becomes
     "2027-2025" and "120+" becomes "+120". */
  unicode-bidi: isolate;
}
[dir="rtl"] .hp-fig-num {
  direction: ltr;
  text-align: right;
}
.hp-fig-lab {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.35;
  color: var(--text-secondary);
}

/* --- resume + footer ------------------------------------------------------ */
.hp-resume {
  display: block;
  width: 100%;
  margin-top: 16px;
  padding: 12px 0;
  border: 0;
  background: none;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: var(--jf-orange-hover);
  cursor: pointer;
}
.hp-foot {
  margin-top: 30px;
  padding: 16px 0 18px;
  border-top: 1px solid var(--border);
  text-align: center;
}
.hp-foot a {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  text-decoration: none;
}
.hp-foot a:hover { color: var(--brand-primary); }

/* Desktop keeps the same five blocks but stops being one narrow ribbon. */
.view--wide { max-width: 820px; }

/* On a tall screen the five blocks would stop well above the fold and leave a
   dead strip under the footer. Centring the block uses the space without
   stretching anything: the slack splits above the logo and below the footer,
   so there is no single hole and the brand row stays tight to the wordmark.
   When the content is taller than the viewport there is no free space to
   distribute, the rule is inert and the page simply scrolls. */
.view--wide {
  display: flex;
  flex-direction: column;
}
.view--wide .screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.view--wide .hp { width: 100%; }
@media (min-width: 900px) {
  .hp-logo img { height: 52px; }
  .hp-hero { padding-top: 36px; }
  .hp-mark { font-size: 62px; }
  .hp-mark-sub { font-size: 17px; }
  .hp-lead { font-size: 17px; max-width: 40ch; }
  .hp-plans { grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 32px; }
  .hp-free { margin-top: 16px; }
  .hp-figures { margin-top: 40px; }
}


.stat-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-top: 16px;
}
.stat {
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  padding: 10px 8px;
  text-align: center;
}
.stat .s-num {
  font-size: 17px;
  font-weight: 800;
  color: var(--brand-primary);
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.stat .s-lab {
  font-size: 9px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 1px;
  line-height: 1.25;
}

/* ----------------------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 0 20px;
  border-radius: 15px;
  border: 1px solid transparent;
  background: var(--brand-primary);
  color: #fff;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -.01em;
  cursor: pointer;
  width: 100%;
  transition: transform .14s var(--ease), background .16s var(--ease);
}
.btn:active { transform: scale(.985); }
.btn[disabled] { opacity: .45; pointer-events: none; }
.btn-accent {
  background: linear-gradient(135deg, var(--jf-orange) 0%, var(--jf-amber) 100%);
  color: #241300;
}
.btn-outline {
  background: transparent;
  color: var(--brand-primary);
  border-color: var(--border-strong);
}
.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  font-weight: 700;
  min-height: 48px;
}
.btn-sm { min-height: 44px; font-size: 13px; padding: 0 14px; width: auto; border-radius: 13px; }
.btn-block { width: 100%; }

.btn-row { display: flex; gap: 8px; margin-top: 12px; }
.btn-row > .btn { flex: 1; }

.cta-block { display: grid; gap: 8px; margin-top: 18px; }

/* ------------------------------------------------------------------- chips */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tap);
  padding: 0 13px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.chip.selected {
  border-color: var(--jf-orange);
  background: var(--surface-tint);
  color: var(--jf-gold-dark);
}
.chip.small { min-height: var(--tap); padding: 0 12px; font-size: 12px; }
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-secondary);
  font-size: 10.5px;
  font-weight: 600;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pill.amber { background: var(--jf-tint); color: var(--jf-gold-dark); }
.pill.green { background: var(--state-meets-bg); color: var(--state-meets); }

/* ------------------------------------------------------------------- cards */
.card {
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 15px;
  box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: 10px; }
.card-title { font-size: 14px; font-weight: 800; letter-spacing: -.01em; }
.card-sub { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; line-height: 1.45; }

.section { margin-top: 18px; }
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.section-head h2 { font-size: 16px; font-weight: 800; }
.section-head .sh-meta { font-size: 11px; color: var(--text-muted); }

/* ==========================================================================
   CHINA CAMPUS PERSONALITY
   The free game owns this block. It is deliberately the only place in the app
   where a photograph fills the screen edge to edge: the paid flow stays a
   document, the game behaves like a magazine page.

   Three decisions worth keeping:
   - Photography bleeds with negative margins because .view already carries the
     16px gutter; the alternative was a second layout shell for one screen.
   - Photography is the only variable colour. Accent stays brand orange, so the
     four cities never look like four different products.
   - Every tap target is at least 48px, and the selected state changes border,
     fill and the mark at once, so it survives sunlight and colour blindness.
   ========================================================================== */

/* --- intro ---------------------------------------------------------------- */
/* Poster + sheet. The photograph fills whatever the copy does not need, and the
   copy rides on a sheet pinned to the bottom edge, so the screen stays composed
   at 568px and at 932px without a single hard-coded height. Growing the layout
   is done through flex rather than percentage heights: the view's height comes
   from `flex: 1` on a `min-height: 100dvh` shell, which percentages do not
   resolve against. */
.view--fill { display: flex; flex-direction: column; }
.view--fill > .screen { flex: 1 1 auto; display: flex; flex-direction: column; }
.pz { position: relative; flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.pz-hero {
  position: absolute;
  top: -14px;
  inset-inline: -16px;
  bottom: 0;
  overflow: hidden;
  background: var(--jf-navy);
  /* The photo is painted across the whole card and the type sheet sits on top
     of it. Without this the hero box answered every hit test over the sheet,
     so "Start the quiz" looked alive but never received the tap. Nothing
     inside the hero is interactive — take it out of pointer hit-testing. */
  pointer-events: none;
}
.pz-hero img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 38%; }
/* The scrim only exists to soften the top edge under the sticky header; the
   sheet carries the type, so the photograph is never muddied to earn contrast. */
.pz-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(6, 16, 30, .34) 0%, rgba(6, 16, 30, .04) 22%, rgba(6, 16, 30, 0) 100%);
  z-index: 2;
}
.pz-kicker {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--jf-orange-hover);
}
.pz-h1 {
  margin-top: 8px;
  font-size: clamp(26px, 8vw, 34px);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -.03em;
  color: var(--brand-primary);
}
.pz-tag {
  margin-top: 10px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--jf-orange-hover);
  max-width: 30ch;
}

.pz-body {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  margin-top: auto;
  margin-inline: -16px;
  padding: 24px 20px calc(22px + env(safe-area-inset-bottom));
  border-radius: 26px 26px 0 0;
  background: var(--surface-muted);
  box-shadow: 0 -16px 46px rgba(6, 16, 30, .22);
}
.pz-sub { font-size: 15px; line-height: 1.5; color: var(--text-secondary); }
.pz-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 14px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-muted);
}
.pz-meta span { display: inline-flex; align-items: center; gap: 7px; }
.pz-pip { width: 5px; height: 5px; border-radius: 50%; background: var(--jf-orange); }
.pz-cta { margin-top: auto; padding-top: 22px; display: grid; gap: 6px; }
.pz-resume {
  min-height: 44px;
  border: 0;
  background: none;
  color: var(--text-secondary);
  font-size: 14px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.pz-flag {
  margin-top: 16px;
  padding: 11px 14px;
  border-radius: 12px;
  background: var(--surface-tint);
  border: 1px solid var(--jf-warm-border);
  color: var(--state-prep);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
}

/* --- question ------------------------------------------------------------- */
.qz-rail { display: flex; gap: 5px; margin-bottom: 14px; }
.qz-rail span {
  flex: 1;
  height: 4px;
  border-radius: 99px;
  background: var(--border);
  transition: background .22s var(--ease);
}
.qz-rail span.past { background: #f7c98b; }
.qz-rail span.now { background: var(--jf-orange); }
.qz-count {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.qz-title {
  margin-top: 9px;
  font-size: clamp(21px, 5.6vw, 25px);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -.024em;
  color: var(--brand-primary);
}
/* The "multiple choice" qualifier lives inside the heading, not in a hint line
   below it: it belongs to the question, it wraps with it, and it is impossible
   to read one without the other. */
.qz-multi {
  display: inline;
  font-size: .64em;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-secondary);
  white-space: normal;
}
.qz-band {
  position: relative;
  margin-top: 14px;
  height: 128px;
  border-radius: 16px;
  overflow: hidden;
  background: var(--surface-sunken);
}
.qz-band img { width: 100%; height: 100%; object-fit: cover; }
.qz-band::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(6, 16, 30, .12), rgba(6, 16, 30, .28));
  z-index: 2;
}

.qz-opts { display: grid; gap: 9px; margin-top: 16px; }
.qz-opts--photo { grid-template-columns: 1fr 1fr; gap: 10px; }

/* Every photo also carries a 20px WebP as its own background, so a slow or
   failed request leaves a soft colour field instead of a grey hole. The tile is
   redrawn through a blurred pseudo-element: a 20px thumbnail scaled to 200px
   reads as a pixel grid, blurred it reads as the photo's own palette. */
.pz-hero,
.qz-band,
.qz-thumb,
.pr-hero {
  background-size: cover;
  background-position: 50% 42%;
  background-repeat: no-repeat;
}
.pz-hero::before,
.qz-band::before,
.qz-thumb::before,
.pr-hero::before {
  content: "";
  position: absolute;
  inset: -24px;
  background-image: inherit;
  background-size: cover;
  background-position: 50% 42%;
  filter: blur(18px);
  z-index: 0;
}
.pz-hero img,
.qz-band img,
.qz-thumb img,
.pr-hero img { position: relative; z-index: 1; }
img.is-broken { opacity: 0; }

.qz-opt-body { flex: 1 1 auto; min-width: 0; }

.qz-opt {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  min-height: 56px;
  padding: 12px 13px;
  border: 1.5px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
  text-align: start;
  cursor: pointer;
  font-size: 15px;
  line-height: 1.4;
  color: var(--text-primary);
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.qz-opt:hover { border-color: var(--border-strong); }
.qz-opt.selected { border-color: var(--jf-orange); background: var(--surface-tint); }
.qz-opt.selected .qz-mark {
  background: var(--jf-orange);
  border-color: var(--jf-orange);
  color: #fff;
}
.qz-mark {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1.5px solid var(--border-strong);
  display: grid;
  place-items: center;
  font-size: 12px;
  line-height: 1;
  font-weight: 800;
  color: transparent;
  transition: background .15s, border-color .15s, color .15s;
}
.qz-opt--multi .qz-mark { border-radius: 7px; }

.qz-opt--photo {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  min-height: 0;
  padding: 0;
  overflow: hidden;
}
.qz-thumb {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--surface-sunken);
  /* The blurred fallback bleeds past its box by design; clip it here so the
     label underneath keeps a clean white plate. */
  overflow: hidden;
}
.qz-thumb img { width: 100%; height: 100%; object-fit: cover; }
.qz-lab { display: block; padding: 9px 11px 11px; font-size: 13.5px; font-weight: 600; line-height: 1.35; }
/* A hollow ring over the photograph, not a solid dot: an empty white pill read
   as a broken control next to four unselected cards. */
.qz-opt--photo .qz-mark {
  position: absolute;
  top: 8px;
  inset-inline-end: 8px;
  width: 24px;
  height: 24px;
  z-index: 3;
  background: rgba(6, 16, 30, .26);
  border: 1.5px solid rgba(255, 255, 255, .92);
  box-shadow: 0 1px 6px rgba(6, 16, 30, .26);
}
.qz-opt--photo.selected .qz-mark { background: var(--jf-orange); border-color: #fff; }

.qz-note {
  margin-top: 12px;
  padding: 10px 13px;
  border-radius: 12px;
  background: var(--state-prep-bg);
  border: 1px solid #f4d9a8;
  color: #7a4600;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.45;
}
.qz-nav { display: grid; gap: 8px; margin-top: 20px; }

/* --- result --------------------------------------------------------------- */
.pr-hero {
  position: relative;
  margin: -14px -16px 0;
  /* 125vw is a 4:5 crop at full width. `aspect-ratio` cannot be used here: a
     max-height on an aspect-ratio box shrinks the *width*, which left a white
     gutter on 320x568 screens. An explicit height keeps the bleed intact. */
  height: 125vw;
  max-height: 60vh;
  overflow: hidden;
  background: var(--jf-navy);
}
.pr-hero img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 44%; }
.pr-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(6, 16, 30, .1) 0%, rgba(6, 16, 30, .02) 26%, rgba(6, 16, 30, .52) 58%, rgba(6, 16, 30, .94) 100%);
  z-index: 2;
}
.pr-hero-in { position: absolute; z-index: 3; inset-inline: 18px; bottom: 18px; }
.pr-kicker {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .74);
}
.pr-title {
  margin-top: 8px;
  font-size: clamp(28px, 8.8vw, 37px);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -.032em;
  color: #fff;
}
.pr-city {
  display: inline-block;
  margin-top: 11px;
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--jf-amber);
}

.pr-sec { margin-top: 22px; }
.pr-lab {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.pr-text { margin-top: 9px; font-size: 16px; line-height: 1.58; color: var(--text-primary); }
.pr-traits { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 11px; }
.pr-tag {
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 13.5px;
  font-weight: 700;
  color: var(--brand-primary);
}
.pr-tag:first-child {
  background: var(--surface-tint);
  border-color: var(--jf-warm-border);
  color: var(--state-prep);
}
.pr-moment {
  margin-top: 22px;
  padding: 16px 16px 17px;
  border-radius: 16px;
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-inline-start: 3px solid var(--jf-orange);
}
.pr-moment .pr-text { margin-top: 8px; font-size: 15px; color: var(--text-secondary); }
.pr-alt { margin-top: 17px; font-size: 14px; color: var(--text-muted); }

.pr-share { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--border-subtle); }
.pr-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-top: 13px; }
.pr-btns .btn { min-height: 48px; padding: 0 12px; font-size: 13.5px; }
.pr-btns .btn--wide { grid-column: 1 / -1; }
.pr-credit { margin-top: 13px; font-size: 11.5px; color: var(--text-muted); }

.pr-cta {
  margin-top: 26px;
  padding: 20px 17px;
  border-radius: 18px;
  background: var(--surface);
  border: 1px solid var(--border);
}
.pr-cta-sub { margin-top: 10px; font-size: 14px; line-height: 1.5; color: var(--text-secondary); }
.pr-fine { margin-top: 18px; font-size: 12px; line-height: 1.55; color: var(--text-muted); }

/* Letter-spacing and uppercasing are Latin-only. Tracking pulls Arabic joined
   letters apart and misplaces Thai and Bengali marks above the baseline. */
html[lang="ar"] .pr-city,
html[lang="bn"] .pr-city,
html[lang="th"] .pr-city {
  letter-spacing: 0;
  text-transform: none;
  font-size: 15px;
}
html[lang="ar"] .pr-kicker,
html[lang="bn"] .pr-kicker,
html[lang="th"] .pr-kicker,
html[lang="ar"] .pz-kicker,
html[lang="bn"] .pz-kicker,
html[lang="th"] .pz-kicker,
html[lang="ar"] .qz-count,
html[lang="bn"] .qz-count,
html[lang="th"] .qz-count,
html[lang="ar"] .qz-title,
html[lang="bn"] .qz-title,
html[lang="th"] .qz-title,
html[lang="ar"] .pr-lab,
html[lang="bn"] .pr-lab,
html[lang="th"] .pr-lab {
  letter-spacing: .04em;
  text-transform: none;
}
/* Negative tracking on a title is a Latin habit; Arabic joins and the stacked
   marks in Thai and Bengali need the letters left alone. */
html[lang="ar"] .qz-title,
html[lang="bn"] .qz-title,
html[lang="th"] .qz-title {
  letter-spacing: 0;
}

@media (min-width: 640px) {
  .qz-band { height: 176px; }
  .pr-hero { height: 380px; max-height: none; }
}

/* On a desktop the poster would otherwise stretch to the full window height and
   magnify a landscape photograph into a narrow slice. Capping the card keeps
   the same crop ratio the phone gets. */
@media (min-width: 900px) and (min-height: 720px) {
  .view--fill > .screen { justify-content: center; }
  .pz {
    max-height: 780px;
    border-radius: 26px;
    overflow: hidden;
    box-shadow: 0 22px 60px rgba(6, 16, 30, .16);
  }
  .pz-body { border-radius: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .screen { animation: none; }
  .qz-rail span,
  .qz-opt,
  .qz-mark,
  .btn { transition: none; }
}

/* ---------------------------------------------------------------- pricing */
.price-grid { display: grid; gap: 12px; margin-top: 16px; }

.plan {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: 18px 16px;
  position: relative;
}
.plan.featured {
  border-color: var(--jf-orange);
  box-shadow: 0 10px 30px rgba(255, 138, 0, .16);
}
.plan .p-flag {
  position: absolute;
  inset-block-start: -10px;
  inset-inline-start: 16px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 4px 9px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--jf-orange), var(--jf-amber));
  color: #241300;
}
.plan h3 { font-size: 16px; font-weight: 800; }
.plan .p-sub { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; line-height: 1.4; }
.plan .p-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 12px;
}
.plan .p-amount {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -.03em;
  color: var(--brand-primary);
  font-variant-numeric: tabular-nums;
}
.plan .p-period { font-size: 11.5px; color: var(--text-muted); font-weight: 600; }
.plan ul { margin-top: 12px; display: grid; gap: 7px; }
.plan li {
  display: flex;
  gap: 8px;
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.4;
}
.plan li .tickmark {
  flex: 0 0 auto;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--state-meets-bg);
  color: var(--state-meets);
  display: grid;
  place-items: center;
  font-size: 8px;
  font-weight: 900;
  margin-top: 1px;
}
.plan .p-cta { margin-top: 14px; }
.plan .p-note {
  margin-top: 8px;
  font-size: 10px;
  color: var(--text-muted);
  text-align: center;
  line-height: 1.4;
}

.demo-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--surface-sunken);
  color: var(--text-muted);
}

/* ------------------------------------------------------------------ forms */
.field { margin-top: 14px; }
.field > label {
  display: block;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 6px;
}
.field .hint { font-size: 10.5px; color: var(--text-muted); margin-top: 5px; line-height: 1.4; }

.input, .select {
  width: 100%;
  min-height: 50px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-primary);
  font-size: 15px;
  font-family: inherit;
  -webkit-appearance: none;
  appearance: none;
}
.input:focus, .select:focus {
  border-color: var(--jf-orange);
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 138, 0, .14);
}
.select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%238a94a6' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-inline-end: 38px;
}
[dir="rtl"] .select { background-position: left 14px center; }

.input-row { display: flex; gap: 8px; }
.input-row > * { min-width: 0; }

.num-note { font-size: 11px; color: var(--text-muted); margin-top: 6px; }

/* --------------------------------------------------------------- uni list */
.search-wrap { position: relative; margin-top: 4px; }
.search-list { display: grid; gap: 7px; margin-top: 12px; overflow-x: hidden; }

.uni-item, .prog-item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: start;
  cursor: pointer;
  min-height: 56px;
}
.uni-item:active, .prog-item:active { background: var(--surface-tint); }
.ui-logo {
  flex: 0 0 auto;
  width: 36px; height: 36px;
  border-radius: 9px;
  border: 1px solid var(--border-subtle);
  background: #fff;
  display: grid;
  place-items: center;
  overflow: hidden;
}
.ui-logo img { width: 100%; height: 100%; object-fit: contain; padding: 3px; }
.ui-logo.on-dark { background: var(--jf-navy); border-color: transparent; }
.ui-logo.on-dark img { padding: 5px; }
.ui-body { flex: 1; min-width: 0; }
.ui-title {
  display: block;
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.ui-sub {
  display: block;
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.ui-chev { flex: 0 0 auto; color: var(--text-muted); }

/* ------------------------------------------------------------ match cards */
.match-card {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.match-card + .match-card { margin-top: 12px; }

.match-media {
  position: relative;
  height: 96px;
  background: var(--jf-navy);
  overflow: hidden;
}
.match-media::before {
  content: "";
  position: absolute;
  inset: -8%;
  background-image: var(--cover, none);
  background-size: cover;
  background-position: center;
  opacity: .4;
  filter: blur(7px) saturate(.85);
  transform: scale(1.05);
}
.match-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11, 31, 58, .18) 0%, rgba(11, 31, 58, .84) 100%);
}
.match-head {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  gap: 10px;
  padding: 10px 12px;
}
.match-logo {
  width: 40px; height: 40px;
  border-radius: 10px;
  background: #fff;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .5);
}
.match-logo img { width: 100%; height: 100%; object-fit: contain; padding: 4px; }
.match-logo.on-dark { background: var(--jf-navy); border-color: rgba(255, 255, 255, .22); }
.match-logo.on-dark img { padding: 6px; }
.match-head .mh-text { flex: 1; min-width: 0; }
.match-head .mh-uni {
  color: #fff;
  font-size: 14px;
  font-weight: 800;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.match-head .mh-city {
  color: rgba(255, 255, 255, .72);
  font-size: 11px;
  margin-top: 1px;
}

.match-body { padding: 12px 13px 14px; }
.match-name {
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.match-meta { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }

.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: -.01em;
}
.status-chip::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}
.st-meets { background: var(--state-meets-bg); color: var(--state-meets); }
.st-prep { background: var(--state-prep-bg); color: var(--state-prep); }
.st-verify { background: var(--state-verify-bg); color: var(--state-verify); }
.st-blocked { background: var(--state-blocked-bg); color: var(--state-blocked); }

.match-reasons { margin-top: 10px; display: grid; gap: 5px; }
.match-reasons li {
  display: flex;
  gap: 7px;
  font-size: 11.5px;
  color: var(--text-secondary);
  line-height: 1.4;
}
.match-reasons li::before {
  content: "";
  flex: 0 0 auto;
  width: 4px;
  height: 4px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--jf-gold);
}

.match-blocker {
  margin-top: 10px;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  background: var(--state-blocked-bg);
  border: 1px solid #f6cfcc;
  font-size: 11px;
  color: #7d1b15;
  line-height: 1.42;
}
.match-blocker .mb-head {
  font-weight: 800;
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  margin-bottom: 3px;
}

.match-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border-subtle);
  flex-wrap: wrap;
}
.match-foot a {
  font-size: 11px;
  font-weight: 700;
  color: var(--jf-gold-dark);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: var(--tap);
}
.match-foot .mf-src { font-size: 10px; color: var(--text-muted); }

/* ---------------------------------------------------------- check rows */
.check-row {
  display: flex;
  gap: 9px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border-subtle);
}
.check-row:last-child { border-bottom: 0; }
.check-row .cr-dot {
  flex: 0 0 auto;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-top: 5px;
}
.check-row.pass .cr-dot { background: var(--state-meets); }
.check-row.prep .cr-dot { background: var(--state-prep); }
.check-row.unknown .cr-dot { background: var(--state-verify); }
.check-row.fail .cr-dot { background: var(--state-blocked); }
.check-row .cr-body { flex: 1; min-width: 0; }
.check-row .cr-label {
  font-size: 12px;
  font-weight: 700;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: baseline;
}
.check-row .cr-state { font-size: 10px; font-weight: 800; letter-spacing: .02em; white-space: nowrap; }
.check-row.pass .cr-state { color: var(--state-meets); }
.check-row.prep .cr-state { color: var(--state-prep); }
.check-row.unknown .cr-state { color: var(--state-verify); }
.check-row.fail .cr-state { color: var(--state-blocked); }
.check-row .cr-detail {
  font-size: 11px;
  color: var(--text-secondary);
  margin-top: 2px;
  line-height: 1.42;
  overflow-wrap: anywhere;
}
.check-row .cr-published {
  font-size: 10px;
  color: var(--text-muted);
  margin-top: 3px;
  padding-inline-start: 7px;
  border-inline-start: 2px solid var(--border);
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------- scholarship */
.sch-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: 14px;
  text-align: start;
  width: 100%;
  cursor: pointer;
  display: block;
}
.sch-card + .sch-card { margin-top: 10px; }
.sch-card.verified { border-color: #cbe6d9; }
.sch-top { display: flex; align-items: flex-start; gap: 10px; }
.sch-badge {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  font-size: 16px;
  background: var(--surface-tint);
  color: var(--jf-gold-dark);
}
.sch-card.verified .sch-badge { background: var(--state-meets-bg); color: var(--state-meets); }
.sch-title {
  font-size: 13.5px;
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: -.01em;
  overflow-wrap: anywhere;
}
.sch-univ { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.sch-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--border-subtle);
  flex-wrap: wrap;
}
.sch-foot .sf-right { font-size: 10.5px; color: var(--text-muted); }

.verify-band {
  display: flex;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--state-prep-bg);
  border: 1px solid #f6dfb6;
  font-size: 11px;
  color: #7a4600;
  line-height: 1.42;
  margin-top: 12px;
}
.verify-band .vb-icon { flex: 0 0 auto; }

.fund-grid { display: grid; gap: 2px; margin-top: 10px; }
.fund-row {
  display: flex;
  gap: 10px;
  justify-content: space-between;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px dashed var(--border-subtle);
  font-size: 12px;
}
.fund-row:last-child { border-bottom: 0; }
.fund-row .fr-key { color: var(--text-muted); flex: 0 0 auto; max-width: 46%; }
.fund-row .fr-val {
  text-align: end;
  font-weight: 700;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.fund-row .fr-val.unknown { color: var(--text-muted); font-weight: 600; font-style: italic; }

/* --------------------------------------------------------------- timeline */
.timeline { position: relative; padding-inline-start: 18px; margin-top: 10px; }
.timeline::before {
  content: "";
  position: absolute;
  inset-block: 6px;
  inset-inline-start: 5px;
  width: 2px;
  background: var(--border);
}
.tl-item { position: relative; padding-bottom: 14px; }
.tl-item::before {
  content: "";
  position: absolute;
  inset-inline-start: -17px;
  top: 4px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--jf-gold);
}
.tl-item.deadline::before { border-color: var(--jf-orange); background: var(--jf-tint); }
.tl-date { font-size: 10.5px; font-weight: 800; color: var(--jf-gold-dark); letter-spacing: .02em; }
.tl-title { font-size: 12.5px; font-weight: 700; margin-top: 2px; overflow-wrap: anywhere; }
.tl-sub { font-size: 10.5px; color: var(--text-muted); }

/* ----------------------------------------------------------------- tasks */
.task-row {
  display: flex;
  gap: 11px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border-subtle);
  align-items: flex-start;
}
.task-row:last-child { border-bottom: 0; }

.tick {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  border-radius: 8px;
  border: 1.5px solid var(--border-strong);
  background: var(--surface);
  cursor: pointer;
  display: grid;
  place-items: center;
  color: transparent;
  font-size: 13px;
  font-weight: 900;
  margin-top: 1px;
  padding: 0;
}
.tick.done {
  background: var(--state-meets);
  border-color: var(--state-meets);
  color: #fff;
}

.task-body { flex: 1; min-width: 0; }
.task-title {
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.task-row.done .task-title { text-decoration: line-through; color: var(--text-muted); }
.task-sub {
  font-size: 10.5px;
  color: var(--text-muted);
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.task-pills { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.task-note {
  font-size: 10.5px;
  color: var(--jf-gold-dark);
  margin-top: 4px;
  padding-inline-start: 7px;
  border-inline-start: 2px solid var(--jf-gold);
  overflow-wrap: anywhere;
}
.task-actions { margin-top: 6px; display: flex; gap: 6px; flex-wrap: wrap; }

.progress-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
}
.progress-line .pl-bar {
  flex: 1;
  height: 7px;
  border-radius: 99px;
  background: var(--surface-sunken);
  overflow: hidden;
}
.progress-line .pl-bar > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--jf-orange), var(--jf-amber));
  border-radius: 99px;
  transition: width .3s var(--ease);
}
.progress-line .pl-num { font-size: 11.5px; font-weight: 800; color: var(--brand-primary); white-space: nowrap; }

/* ---------------------------------------------------------------- funnel */
.funnel { display: grid; gap: 2px; margin-top: 10px; }
.funnel-step {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 11.5px;
}
.funnel-step .fs-label { flex: 1; min-width: 0; color: var(--text-secondary); overflow-wrap: anywhere; }
.funnel-step .fs-count {
  font-weight: 800;
  color: var(--brand-primary);
  font-variant-numeric: tabular-nums;
  font-size: 12.5px;
}
.funnel-step + .funnel-step { border-top: 1px dashed var(--border-subtle); }

/* --------------------------------------------------------------- compare */
.compare-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin-top: 6px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
}
.compare-table {
  border-collapse: collapse;
  min-width: max-content;
  width: 100%;
  font-size: 11.5px;
}
.compare-table th, .compare-table td {
  padding: 9px 11px;
  text-align: start;
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: top;
}
.compare-table thead th {
  position: sticky;
  top: 0;
  background: var(--surface-muted);
  font-size: 10.5px;
  font-weight: 800;
  color: var(--brand-primary);
  min-width: 148px;
  max-width: 220px;
  overflow-wrap: anywhere;
}
.compare-table tbody th {
  font-weight: 700;
  color: var(--text-muted);
  font-size: 10.5px;
  min-width: 104px;
  max-width: 124px;
  background: var(--surface);
  position: sticky;
  inset-inline-start: 0;
  z-index: 1;
}
.compare-table td { min-width: 148px; max-width: 220px; overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- sheets */
.sheet {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.sheet[hidden] { display: none; }
.sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(11, 31, 58, .5);
  backdrop-filter: blur(2px);
}
.sheet-panel {
  position: relative;
  width: 100%;
  max-width: var(--maxw);
  max-height: 88vh;
  max-height: 88dvh;
  background: var(--surface);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  padding: 8px 16px 18px;
  padding-bottom: max(18px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  animation: sheet-up .26s var(--ease);
}
@keyframes sheet-up {
  from { transform: translateY(28px); opacity: .6; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .sheet-panel { animation: none; }
}
.sheet-handle {
  width: 38px; height: 4px;
  border-radius: 99px;
  background: var(--border-strong);
  margin: 4px auto 10px;
  flex: 0 0 auto;
}
.sheet-title {
  font-size: 17px;
  font-weight: 800;
  margin-bottom: 10px;
  flex: 0 0 auto;
  overflow-wrap: anywhere;
}
.sheet-body {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1;
  min-height: 0;
  padding-bottom: 6px;
}
.sheet-close { flex: 0 0 auto; margin-top: 10px; }

.sheet textarea.input {
  min-height: 96px;
  padding: 12px 14px;
  resize: vertical;
  line-height: 1.5;
}

/* ----------------------------------------------------------------- toast */
.toast {
  position: fixed;
  inset-block-end: 22px;
  inset-inline: 0;
  margin: 0 auto;
  width: max-content;
  max-width: min(92vw, 420px);
  padding: 11px 16px;
  border-radius: 999px;
  background: rgba(11, 31, 58, .95);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  text-align: center;
  z-index: 120;
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  transition: opacity .22s var(--ease), transform .22s var(--ease);
}
.toast.show { opacity: 1; transform: none; }

/* --------------------------------------------------------------- states */
.empty {
  text-align: center;
  padding: 30px 18px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface);
  margin-top: 14px;
}
.empty .e-icon { font-size: 26px; margin-bottom: 8px; }
.empty .e-title { font-size: 14px; font-weight: 800; }
.empty .e-text { font-size: 12px; color: var(--text-muted); margin-top: 5px; line-height: 1.5; }
.empty .btn { margin-top: 14px; }

.loading-state {
  display: grid;
  place-items: center;
  gap: 14px;
  padding: 48px 20px;
  text-align: center;
}
.spinner {
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 3px solid var(--border);
  border-top-color: var(--jf-orange);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2s; }
}
.loading-state .l-text { font-size: 13px; font-weight: 700; color: var(--brand-primary); }
.loading-state .l-sub { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

.skeleton {
  border-radius: var(--radius);
  background: linear-gradient(90deg, #f1f3f6 25%, #f8f9fb 37%, #f1f3f6 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease infinite;
  height: 74px;
  margin-top: 8px;
}
@keyframes shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; background: #f1f3f6; }
}

/* --------------------------------------------------------------- footer */
.foot-note {
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px solid var(--border-subtle);
  font-size: 10px;
  color: var(--text-muted);
  line-height: 1.55;
  text-align: center;
}
.foot-note a { color: var(--jf-gold-dark); }

/* ------------------------------------------------------------- dashboard */
.dash-hero {
  border-radius: var(--radius-xl);
  padding: 20px 18px;
  background: linear-gradient(155deg, #0d2a4a, var(--jf-navy) 72%);
  color: #fff;
}
.dash-hero h1 { color: #fff; font-size: 21px; font-weight: 800; letter-spacing: -.02em; }
.dash-hero .dh-sub { font-size: 12px; color: rgba(255, 255, 255, .72); margin-top: 5px; line-height: 1.4; }
.dash-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 16px; }
.dash-stat {
  background: rgba(255, 255, 255, .09);
  border-radius: var(--radius);
  padding: 10px 9px;
  text-align: center;
}
.dash-stat .ds-num { font-size: 18px; font-weight: 800; color: var(--jf-amber); }
.dash-stat .ds-lab { font-size: 9px; color: rgba(255, 255, 255, .66); margin-top: 1px; line-height: 1.25; }

.quick-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; margin-top: 12px; }
.quick-tile {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 13px 12px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  text-align: start;
  cursor: pointer;
  min-height: 74px;
}
.quick-tile .qt-icon { font-size: 17px; }
.quick-tile .qt-label { font-size: 12px; font-weight: 700; line-height: 1.3; }
.quick-tile .qt-meta { font-size: 10px; color: var(--text-muted); }

/* ------------------------------------------------------------- utilities */
.row { display: flex; align-items: center; gap: 8px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.row-between > strong { white-space: nowrap; }
.grow { flex: 1; min-width: 0; }
.mt-4 { margin-top: 4px; }
.mt-8 { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.wrap { overflow-wrap: anywhere; }
.hide { display: none !important; }

/* ------------------------------------------------------------- desktop */
@media (min-width: 720px) {
  body { background: #f2efe7; }
  .app { max-width: 620px; margin: 0 auto; box-shadow: 0 0 60px rgba(11, 31, 58, .08); }
  .topbar { max-width: 620px; }
  .view { padding: 20px 22px 40px; }
  .hero { padding: 34px 28px 28px; }
  .hero h1 { font-size: 34px; }
  .price-grid { grid-template-columns: 1fr 1fr; align-items: start; }
  .stat-row { gap: 10px; }
}

@media (min-width: 1100px) {
  .app { max-width: 680px; }
  .topbar { max-width: 680px; }
  /* The home page uses the wider column so the two plans can sit side by side
     instead of stacking inside a phone-width ribbon. */
  .app.app--wide { max-width: 860px; }
  .app.app--wide .topbar { max-width: 860px; }
}

/* Narrow phones (320px) */
@media (max-width: 344px) {
  .view { padding: 12px 12px 26px; }
  .hero { padding: 20px 15px 18px; }
  .hero h1 { font-size: 24px; }
  .title { font-size: 21px; }
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .plan .p-amount { font-size: 26px; }
  .btn { font-size: 13.5px; padding: 0 14px; }
  .match-head .mh-uni { font-size: 12.5px; }
  .dash-hero h1 { font-size: 18px; }
}

/* ---------------------------------------------------------------- boot */
.boot {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  gap: 14px;
  background: var(--surface-muted);
  z-index: 200;
  transition: opacity .3s var(--ease);
}
.boot[hidden] { display: none; }
.boot-ring {
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 3px solid var(--border);
  border-top-color: var(--jf-orange);
  animation: spin .8s linear infinite;
}
.boot p { font-size: 12px; color: var(--text-muted); }

/* ------------------------------------------------------- target picker ---- */
/* Optional "I already know which university" control on the profile step.
   The database search lives behind this, not on the home page. */
.tp {
  display: block;
  width: 100%;
  margin-top: 16px;
  padding: 13px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: start;
}
.tp--add {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--brand-primary);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.tp--add:hover { border-color: var(--border-strong); }
.tp-plus {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-tint);
  color: var(--jf-orange-hover);
  font-size: 15px;
  line-height: 1;
}
.tp--set { border-color: var(--jf-gold); background: #fffcf6; }
.tp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.tp-lab {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.tp-clear {
  flex: 0 0 auto;
  padding: 4px 8px;
  border: 0;
  background: none;
  color: var(--jf-orange-hover);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.tp-val {
  margin-top: 5px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------- search hint -- */
.search-hint {
  margin-top: 18px;
  padding: 14px 15px;
  border-radius: var(--radius);
  background: var(--surface-sunken);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-secondary);
}
