/* ==========================================================================
   AQAR — UI layer (the design system). Loaded on EVERY front-end page.
   Depends on tokens.css.

   This is the single component library for the whole site. The homepage, the
   interior pages and the TutorLMS catalogue all draw their cards, badges,
   section rhythm and headings from here — so a card is defined ONCE, and
   changing it changes it everywhere.

   It exists because it didn't. The homepage revamp left the theme with two
   parallel libraries (home.css and content.css) that each defined a card and a
   page header, and they immediately began to drift. Homepage-only sections live
   in home.css; interior-page specifics live in pages.css; both sit on this.

   Rules this file keeps:
   1. Tokens are law. There is not one hard-coded brand colour below.
   2. No backdrop-filter. Blurring a surface costs a repaint per frame and, over
      an opaque background, changes no pixels at all.
   ========================================================================== */

/* ==========================================================================
   [hidden] MUST WIN
   The course filter hides cards by setting el.hidden = true. The browser's
   [hidden] rule is `display: none`, but it lives in the UA stylesheet — so ANY
   author `display` declaration beats it, and .ccard/.ccard-empty are both
   `display: flex`. The result was a filter that "worked" in JS and changed
   nothing on screen. Do not remove this rule.
   ========================================================================== */
[hidden] { display: none !important; }

/* ==========================================================================
   SCROLL REVEAL
   Short, small, once. Nothing loops, bounces or flies in. Elements start hidden
   and are released by IntersectionObserver in home.js. If JS never runs, .no-js
   releases everything — the page must never be blank.
   ========================================================================== */
.reveal { opacity: 0; transform: translateY(16px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity .55s var(--ease-soft), transform .55s var(--ease-soft);
  transition-delay: var(--d, 0ms);
}
html.no-js .reveal { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.is-in { opacity: 1 !important; transform: none !important; }
}

/* ==========================================================================
   SECTION RHYTHM
   ========================================================================== */
.hsec { padding: var(--sp-8) 0; }
.hsec-inner { padding: var(--sp-8) 0; }
.hsec-alt { background: var(--c-surface); }
.hsec-line { border-top: 1px solid var(--c-line); border-bottom: 1px solid var(--c-line); }
.hsec-line-b { border-bottom: 1px solid var(--c-line); }
.hsec-dark { background: var(--c-teal-deep); color: #fff; position: relative; overflow: hidden; }
.hsec-dark h1, .hsec-dark h2, .hsec-dark h3 { color: #fff; }

/* The one gradient on the page. Static, painted once, no animation. */
.hsec-glow { position: absolute; inset: 0; pointer-events: none; }

.hsec-head { max-width: 640px; }
.hsec-head--center { margin-inline: auto; text-align: center; }
.hsec-head--wide { max-width: 760px; }
.hsec-eyebrow { display: inline-block; font-size: var(--fs-xs); font-weight: 800;
  text-transform: uppercase; letter-spacing: var(--ls-eyebrow); color: var(--c-turquoise-600);
  margin: 0 0 var(--sp-3); }
.hsec-title { font-size: clamp(1.9rem, 3.6vw, 2.7rem); letter-spacing: -.02em;
  line-height: 1.15; margin: 0; }
.hsec-title--sm { font-size: clamp(1.7rem, 3.2vw, 2.3rem); }
.hsec-lead { margin: var(--sp-4) 0 0; font-size: 1.0625rem; color: var(--c-muted); line-height: var(--lh-body); }
.hsec-dark .hsec-lead { color: rgba(255,255,255,.7); }

/* A closing statement under a section, and the "see all" link after a grid. */
.hsec-kicker { margin: var(--sp-7) 0 0; text-align: center; font-size: 1.1875rem;
  font-weight: 800; letter-spacing: -.02em; color: var(--c-ink); }
.hsec-more { margin: var(--sp-6) 0 0; text-align: center; }

/* CTA akhir (template-parts/sections/cta.php). Shared with the About page, so
   it lives here rather than home.css. Every gap below is a clamp so the rhythm
   opens up gradually on larger screens instead of jumping at a breakpoint. */
.cta-glow {
  background: radial-gradient(780px 430px at 50% 0%, var(--c-turquoise) 0%, transparent 65%);
  opacity: .6;
}
.cta-inner { position: relative; padding: var(--sp-9) 0; text-align: center; }
.cta-title { margin: 0 auto; max-width: 22ch; font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.12; letter-spacing: -.02em; color: #fff; }
.cta-lead { margin: clamp(var(--sp-5), 4vw, var(--sp-7)) auto 0; max-width: 46ch;
  font-size: 1.0625rem; line-height: var(--lh-body); color: rgba(255,255,255,.7); }
.cta-actions { margin: clamp(var(--sp-6), 5vw, var(--sp-8)) auto 0; text-align: center; }
.cta-note { margin: clamp(var(--sp-3), 3vw, var(--sp-5)) 0 0; font-size: 0.8125rem;
  color: rgba(255,255,255,.5); }

@media (min-width: 1024px) {
  .hsec, .hsec-inner { padding: var(--sp-9) 0; }
}

/* ==========================================================================
   GRIDS
   ========================================================================== */
.hgrid { display: grid; gap: var(--sp-5); }
.hgrid-2 { grid-template-columns: repeat(2, 1fr); }
.hgrid-3 { grid-template-columns: repeat(3, 1fr); }
.hgrid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1023px) { .hgrid-3, .hgrid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .hgrid-2, .hgrid-3, .hgrid-4 { grid-template-columns: 1fr; } }

/* ==========================================================================
   BADGES (homepage only — distinct from theme.css .badge)
   ========================================================================== */
.hbadge { display: inline-flex; align-items: center; gap: 4px; border-radius: var(--r-sm);
  padding: 3px 8px; font-size: 10px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .04em; line-height: 1.4; }
.hbadge-included { background: var(--c-tint); color: var(--c-turquoise-700); }
.hbadge-soon { background: var(--c-surface); color: var(--c-faint); }
.hbadge-best { background: var(--c-gold-soft); color: var(--c-warning); }
.hbadge-free { background: var(--c-ink); color: #fff; }
.price-old { font-size: var(--fs-xs); color: var(--c-faint); text-decoration: line-through; }

/* ==========================================================================
   RATING — stars + average + count

   Reviews are REAL as of Phase 11 (this reverses the earlier "no stars, ever"
   rule, which held while AQAR had no review system). The credibility rule is
   unchanged and absolute: no review is ever seeded, written or fabricated.

   A rating row is rendered ONLY when rating_count > 0. Never render this
   component for an unreviewed course: five empty stars reads as "scored zero",
   which is a lie about a course nobody has judged yet. The gate lives in PHP
   (aqar_course_rating()); this file must never be able to draw a 0-star row.

   The fill is a width-clipped overlay, not per-star icons: it gives an exact
   fractional average (4.3 → 86%) with no SVG <clipPath> ids, which would
   collide the moment two cards sit in the same grid.
   ========================================================================== */
.rating { display: flex; align-items: center; gap: 6px; margin: 0; }
.rating-stars { position: relative; display: inline-block; flex: none; }
/* The two star rows must lay out identically, or the gold overlay drifts out of
   register with the grey one underneath it. Same flex, same non-shrinking SVGs. */
.rating-stars-base,
.rating-stars-fill { display: flex; align-items: center; }
.rating-stars svg { flex: none; color: var(--c-line); }
/* The overlay is clipped to width = avg/5. overflow:hidden is what draws the
   fraction, so the row must not wrap and the stars must not shrink to fit. */
.rating-stars-fill { position: absolute; top: 0; left: 0; bottom: 0;
  overflow: hidden; white-space: nowrap; }
.rating-stars-fill svg { color: var(--c-star-rating); }
.rating-avg { font-size: var(--fs-xs); font-weight: 800; color: var(--c-ink); font-variant-numeric: tabular-nums; }
.rating-count { font-size: var(--fs-xs); color: var(--c-faint); }

/* ==========================================================================
   COURSE CARD — the component
   Everything is clamped so real content can never make one card taller than its
   neighbour: 16:9 thumbnail, 2-line title, 1-line instructor. A 60-character
   Malay course title must not break the grid.

   The card's trust signal is still the .ccard-for targeting line ("Untuk
   sesiapa yang…"). The rating row above is additive: an unreviewed course shows
   the tagline and no stars, which is the honest state and will be the normal
   state for a while.
   ========================================================================== */
.ccard { position: relative; display: flex; flex-direction: column; background: var(--c-canvas);
  border: 1px solid var(--c-line); border-radius: var(--r-card); overflow: hidden;
  transition: box-shadow .3s var(--ease), transform .3s var(--ease); }
.ccard:hover { box-shadow: var(--sh-lg); transform: translateY(-4px); }

.ccard-thumb { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9;
  overflow: hidden; background: var(--c-teal-deep); }
.ccard-thumb img { width: 100%; height: 100%; object-fit: cover;
  transition: transform .5s var(--ease); }
.ccard:hover .ccard-thumb img { transform: scale(1.05); }

.ccard-body { display: flex; flex: 1; flex-direction: column; gap: 6px; padding: var(--sp-4); }
.ccard-title { margin: 0; font-size: 0.9375rem; font-weight: 800; line-height: var(--lh-snug);
  letter-spacing: -.01em; color: var(--c-ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 2.6em; }
.ccard-title a { color: inherit; }
.ccard-title a:hover { text-decoration: none; color: var(--c-turquoise-600); }
/* Stretched link: the whole card is clickable, but only the title is a link. */
.ccard-title a::after { content: ""; position: absolute; inset: 0; }

.ccard-instr { margin: 0; font-size: var(--fs-xs); color: var(--c-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ccard-meta { margin: 0; font-size: 11px; color: var(--c-faint); line-height: var(--lh-snug); }
/* The targeting line. It does more work than a fake 4.8 rating ever could,
   because it tells the reader whether this course is for them. */
.ccard-for { margin: 2px 0 0; font-size: 0.8125rem; line-height: var(--lh-snug);
  color: var(--c-ink-2); font-style: italic; }
.ccard-foot { display: flex; align-items: center; gap: var(--sp-2); margin-top: auto; padding-top: var(--sp-2); }

/* Honest empty slot: "more courses coming" without inventing a course. */
.ccard-empty { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-2); padding: var(--sp-6); text-align: center;
  border: 2px dashed var(--c-line); border-radius: var(--r-card); background: var(--c-canvas); }
.ccard-empty-ico { display: grid; place-items: center; width: 48px; height: 48px;
  border: 2px dashed var(--c-line); border-radius: var(--r-pill); color: var(--c-faint); }
.ccard-empty h3 { margin: var(--sp-2) 0 0; font-size: 0.9375rem; font-weight: 800; }
.ccard-empty p { margin: 0; font-size: 0.8125rem; color: var(--c-muted); line-height: var(--lh-body); }

/* ==========================================================================
   FILTER TABS
   ========================================================================== */
.htabs { display: flex; gap: var(--sp-2); overflow-x: auto; padding-bottom: 4px;
  scrollbar-width: none; }
.htabs::-webkit-scrollbar { display: none; }
.htab { white-space: nowrap; border: 1px solid var(--c-line); border-radius: var(--r-pill);
  background: var(--c-canvas); padding: 8px 16px; font-family: inherit; font-size: var(--fs-sm);
  font-weight: 700; color: var(--c-muted); cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background var(--dur) var(--ease); }
.htab:hover { border-color: var(--c-turquoise-300); color: var(--c-turquoise-700); }
.htab.is-active { background: var(--c-ink); border-color: var(--c-ink); color: #fff; }

/* ==========================================================================
   GURU (instructor) CARD + ROW
   ========================================================================== */
.gcard { display: flex; flex-direction: column; background: var(--c-canvas);
  border: 1px solid var(--c-line); border-radius: var(--r-lg); overflow: hidden;
  transition: box-shadow .3s var(--ease), transform .3s var(--ease); }
.gcard:hover { box-shadow: var(--sh-lg); transform: translateY(-4px); }
.gcard-photo { position: relative; width: 100%; aspect-ratio: 1 / 1; overflow: hidden; background: var(--c-surface); }
.gcard-photo img { width: 100%; height: 100%; object-fit: cover; }
.gcard-body { padding: var(--sp-4); }
.gcard-name { margin: 0 0 2px; font-size: var(--fs-body); font-weight: 800; }
.gcard-role { margin: 0; font-size: var(--fs-xs); color: var(--c-muted); }

/* ==========================================================================
   STATS
   ========================================================================== */
.stat-num { font-size: 2.25rem; font-weight: 800; letter-spacing: -.03em; line-height: 1.1;
  color: var(--c-ink); font-variant-numeric: tabular-nums; }
.stat-lab { margin: var(--sp-1) 0 0; font-size: var(--fs-xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: var(--c-faint); }
@media (min-width: 640px) { .stat-num { font-size: 3rem; } }

/* ==========================================================================
   TESTIMONIALS
   ========================================================================== */
.tcard { display: flex; flex-direction: column; gap: var(--sp-4); background: var(--c-canvas);
  border: 1px solid var(--c-line); border-radius: var(--r-lg); padding: var(--sp-5); }
.tcard-quote { margin: 0; font-size: 0.9375rem; line-height: var(--lh-body); color: var(--c-ink-2); }
.tcard-who { display: flex; align-items: center; gap: var(--sp-3); margin-top: auto; }
.tcard-avatar { width: 40px; height: 40px; border-radius: var(--r-pill); flex: none; object-fit: cover;
  display: grid; place-items: center; background: var(--c-turquoise); color: #fff;
  font-size: var(--fs-xs); font-weight: 800; }
.tcard-name { margin: 0; font-size: var(--fs-sm); font-weight: 800; }
.tcard-role { margin: 0; font-size: var(--fs-xs); color: var(--c-faint); }

/* ==========================================================================
   BLOG POST CARD — Artikel index + category/tag/author archives.
   Named .artcard, NOT .pcard — .pcard already means the PRICING card (the
   RM29/RM192 plan cards further down this file). Also deliberately not a
   reuse of .ccard: .ccard is the card that takes money (course catalogue),
   and coupling blog changes to it is a trap. Structurally a cousin of
   .ccard / .gcard / .tcard.

   Must render correctly with NO featured image (the owner's first posts have
   none) — the .artcard--no-media modifier drops the thumb and gives the body
   its own top padding, so the result reads as a deliberate text-first card,
   never a broken one missing an image.
   ========================================================================== */
.artcard { position: relative; display: flex; flex-direction: column; background: var(--c-canvas);
  border: 1px solid var(--c-line); border-radius: var(--r-card); overflow: hidden;
  transition: box-shadow .3s var(--ease), transform .3s var(--ease); }
.artcard:hover { box-shadow: var(--sh-lg); transform: translateY(-4px); }

.artcard-thumb { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9;
  overflow: hidden; background: var(--c-teal-deep); }
.artcard-thumb img { width: 100%; height: 100%; object-fit: cover;
  transition: transform .5s var(--ease); }
.artcard:hover .artcard-thumb img { transform: scale(1.05); }

.artcard-body { display: flex; flex: 1; flex-direction: column; gap: 6px; padding: var(--sp-4); }
.artcard--no-media .artcard-body { padding-top: var(--sp-5); }

.artcard-cat { align-self: flex-start; }

.artcard-title { margin: var(--sp-1) 0 0; font-size: 0.9375rem; font-weight: 800;
  line-height: var(--lh-snug); letter-spacing: -.01em; color: var(--c-ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }
.artcard-title a { color: inherit; }
.artcard-title a:hover { text-decoration: none; color: var(--c-turquoise-600); }
/* Stretched link: the whole card is clickable, but only the title is a link. */
.artcard-title a::after { content: ""; position: absolute; inset: 0; }

.artcard-excerpt { margin: 0; font-size: var(--fs-sm); color: var(--c-muted);
  line-height: var(--lh-body);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }

.artcard-meta { display: flex; align-items: center; gap: var(--sp-2); margin-top: auto;
  padding-top: var(--sp-2); font-size: 11px; color: var(--c-faint); line-height: var(--lh-snug); }
.artcard-meta > * + *::before { content: "\00B7"; margin-right: var(--sp-2); }

/* ==========================================================================
   SHARE ROW — Soal Jawab single AND blog single share the same markup
   (aqar_core_get_share_urls() in aqar-core, .qa-copy-link JS in soaljawab.js —
   that script now loads on both single views, see inc/enqueue.php). Moved here
   from soaljawab.css when the blog needed it too, so it is defined once.
   The "qa-" prefix on the copy-link classes is a naming leftover from where
   this first shipped; a rename is cosmetic, not correctness-critical.
   ========================================================================== */
.qa-share { max-width: var(--content); padding-top: var(--sp-5); border-top: 1px solid var(--c-line); }
.qa-share-label { font-size: var(--fs-sm); font-weight: 600; color: var(--c-ink); margin: 0 0 var(--sp-3); }
.qa-share .share { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0; }
.qa-share .share a,
.qa-copy-link {
  width: 36px; height: 36px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--c-surface); border: 1px solid var(--c-line); color: var(--c-muted);
  cursor: pointer; padding: 0;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.qa-share .share a:hover,
.qa-copy-link:hover { background: var(--c-turquoise); color: #fff; border-color: var(--c-turquoise); text-decoration: none; }
.qa-share .share svg,
.qa-copy-link svg { width: 16px; height: 16px; }

.qa-copy-feedback {
  font-size: var(--fs-sm); font-weight: 600; color: var(--c-success);
  opacity: 0; transition: opacity var(--dur) var(--ease); margin-left: var(--sp-2);
}
.qa-copy-feedback.is-visible { opacity: 1; }

/* ==========================================================================
   FAQ (hand-written accordion — see nav.js)
   ========================================================================== */
.faq { max-width: 800px; margin-inline: auto; }
.faq-q { margin: 0; font-size: inherit; font-weight: inherit; }
.faq-item { border-bottom: 1px solid var(--c-line); }
.faq-btn { display: flex; width: 100%; align-items: center; justify-content: space-between;
  gap: var(--sp-4); padding: var(--sp-5) 0; background: none; border: 0; cursor: pointer;
  font-family: inherit; font-size: 1.0625rem; font-weight: 800; letter-spacing: -.01em;
  line-height: var(--lh-snug); text-align: left; color: var(--c-ink);
  transition: color var(--dur) var(--ease); }
.faq-btn:hover { color: var(--c-turquoise-600); }
.faq-btn svg { flex: none; transition: transform .3s var(--ease); }
.faq-btn[aria-expanded="true"] { color: var(--c-turquoise-600); }
.faq-btn[aria-expanded="true"] svg { transform: rotate(45deg); }
.faq-panel { overflow: hidden; }
.faq-panel[hidden] { display: none; }
.faq-panel-inner { padding: 0 0 var(--sp-5); color: var(--c-muted); line-height: var(--lh-body); }
.faq-panel-inner p:last-child { margin-bottom: 0; }
/* Without JS the accordion cannot open, so every answer stays visible. An FAQ
   that needs JavaScript to be read is an FAQ that Google cannot read either.
   !important because the global [hidden] rule at the top of this file is too. */
html.no-js .faq-panel[hidden] { display: block !important; }

/* ==========================================================================
   TRUST STRIP
   ========================================================================== */
.trust-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.trust-badge { display: inline-flex; align-items: center; gap: var(--sp-2); border-radius: var(--r-pill);
  border: 1px solid var(--c-line); background: var(--c-canvas); padding: 6px 14px;
  font-size: 0.8125rem; font-weight: 700; color: var(--c-ink-2); }


/* ==========================================================================
   CHECK ICON — pricing lists and checklists
   ========================================================================== */
.ico-check { flex: none; margin-top: 4px; color: var(--c-turquoise); }

/* ==========================================================================
   GENERIC CARD, TAG, INSTRUCTOR LINE
   The plain surface the specialised cards (.ccard, .gcard, .tcard) are cousins
   of. Used where a page needs a panel and none of the specialised cards fit —
   Soal Jawab entries, the auth panel, contact details.
   ========================================================================== */
.card { background: var(--c-canvas); border: 1px solid var(--c-line);
  border-radius: var(--r-card); overflow: hidden;
  transition: box-shadow .3s var(--ease), transform .3s var(--ease); }
.card:hover { box-shadow: var(--sh-md); }
.card-body { padding: var(--sp-5); }

.tag { display: inline-block; padding: 4px 10px; border: 1px solid var(--c-line);
  border-radius: var(--r-sm); background: var(--c-surface);
  font-size: var(--fs-xs); font-weight: 600; color: var(--c-muted); }
a.tag:hover { color: var(--c-turquoise-700); border-color: var(--c-turquoise); text-decoration: none; }

.instr { display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); color: var(--c-muted); }
.instr .avatar { display: flex; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 28px; border-radius: var(--r-pill);
  background: var(--c-turquoise); color: #fff; font-size: var(--fs-xs); font-weight: 700; }
/* When .avatar is an <img> (a real byline photo) rather than an initials span. */
.instr img.avatar { object-fit: cover; }
