/* v201: moved verbatim out of catalog.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. */
.pnav{display:flex;align-items:center;flex-wrap:wrap;gap:14px;padding:14px 5%;position:sticky;top:0;z-index:40;background:var(--paper);border-bottom:1px solid var(--stroke)}
.pnav-logo img{height:34px;display:block}
.pnav-links{display:none;gap:26px;margin-left:26px}
@media(min-width:860px){.pnav-links{display:flex}}
.pnav-links a{color:var(--text2);font-size:13px;font-weight:700}
.pnav-links a:hover{color:var(--text);text-decoration:none}
/* R30: below 860px the nav links were display:none with no menu — Courses /
   Departments / How-it-works were unreachable from a phone. The burger folds
   them out as a column inside the (already flex-wrap) nav. */
.pnav-burger{display:none;flex:none;width:34px;height:34px;border-radius:var(--r-sm);border:1px solid var(--stroke);background:none;color:var(--text2);cursor:pointer;align-items:center;justify-content:center;font-size:17px;line-height:1}
.pnav-burger:hover{border-color:var(--stroke-hi);color:var(--text)}
@media(max-width:859.98px){
  .pnav-burger{display:flex}
  .pnav.nav-open .pnav-links{display:flex;flex-direction:column;align-items:flex-start;gap:13px;order:9;flex-basis:100%;margin:4px 0 2px;padding-top:13px;border-top:1px solid var(--stroke)}
}
.pnav-right{margin-left:auto;display:flex;align-items:center;flex-wrap:wrap;gap:9px}
/* R155 Phase 4 port: extra bottom room so the floating cart bar (added
   below, same as build.html) never overlaps the last row of cards —
   build.html's own .wrap carries the identical 120px for the same reason. */
.wrap{max-width:1280px;margin:0 auto;padding:0 5% 120px}

.cat-head{padding:44px 0 8px}
.cat-title{font-size:clamp(26px,3.2vw,40px);font-weight:600;margin:10px 0 8px}
.cat-tools{display:flex;gap:12px;flex-wrap:wrap;align-items:center;margin:22px 0 10px}
.cat-search{flex:1;min-width:230px;display:flex;align-items:center;gap:9px;background:var(--glass);border:1px solid var(--stroke);border-radius:var(--r-sm);padding:11px 15px}
.cat-search input{background:none;border:none;outline:none;color:var(--text);font-family:var(--fb);font-size:13.5px;width:100%}
.cat-search input::placeholder{color:var(--text3)}
.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{color:var(--brand-on);border-color:transparent;background:var(--brand)}
.chips-row{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:26px}
.cat-grid{display:grid;grid-template-columns:1fr;gap:18px;padding-bottom:64px}
@media(min-width:680px){.cat-grid{grid-template-columns:1fr 1fr}}
@media(min-width:1020px){.cat-grid{grid-template-columns:1fr 1fr 1fr}}
.ccard{padding:0;overflow:hidden;transition:transform .28s cubic-bezier(.2,.7,.3,1.2),box-shadow .28s,border-color .28s;display:flex;flex-direction:column}
/* R120: same trap noted in assets/app.css's .btn.btn-x comment —
   [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, so its
   title/price text would render link-blue without this. .ccard.glass scores
   (0,2,0) and wins cleanly, no !important. */
.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:128px;display:flex;align-items:center;justify-content:center;font-size:46px;position:relative}
.cc-thumb::after{content:none}
.t-blue{background:var(--surface-3)}
.t-orange{background:var(--surface-3)}
.t-green{background:var(--surface-3)}
/* R155 Phase 4 port: cc-body used to be the LAST thing inside the card's
   single big <a> (R120) — its bottom padding (18px) was the only space
   between the price row and the card's own bottom edge. Now a sibling
   .cc-actions (added below, never inside an <a> — see that rule's own
   comment) can follow it, and .cc-actions's own first child already
   carries its own top margin (.bpick/.b-free-block/.bcard-actions, all
   copied verbatim from build.html). Left at 18px, the two would stack
   into an 26-30px gap that reads as an accidental double space; trimmed
   to 6px here so the combined gap (6 + that child's own 8-12px margin)
   lands close to build.html's own un-split rhythm instead. */
.cc-body{padding:16px 18px 6px;display:flex;flex-direction:column;flex:1}
.cc-title{font-weight:600;font-size:15px;line-height:1.35;margin:8px 0 4px}
.cc-tutor{font-size:12px;color:var(--text3);font-weight:600;margin-bottom:9px}
.cc-meta{font-size:11.5px;color:var(--text3);font-weight:600;display:flex;gap:12px;margin-bottom:14px}
.cc-foot{display:flex;align-items:center;justify-content:space-between;margin-top:auto}
.cc-price{font-family:var(--fm);font-size:19px;font-weight:700}
.empty{display:none;text-align:center;padding:60px 20px;color:var(--text3)}
.empty.show{display:block}

/* ═══ R155 Phase 4 — "add to plan" ported from build.html ══════════════════
   catalog.html's card used to be ONE big <a class="ccard"> (R120: so right-
   click/ctrl-click/middle-click work anywhere on the card). The new
   interactive controls below — bundle radios, Add/Choose-modules buttons, a
   dynamic module checklist full of checkboxes, a Join-free button — cannot
   be nested inside that anchor without a preventDefault()/stopPropagation()
   on every single one (fragile, and easy to miss on a checklist rebuilt at
   runtime). Instead the card root (.ccard.bcard) now holds TWO children: an
   inner `.cc-link` <a> wrapping only the non-interactive, purely-
   navigational content (thumbnail + title/tutor/meta/price/"View course"),
   and a sibling `.cc-actions` <div> — never inside any <a> — holding every
   interactive control, wired the same delegated-listener way build.html's
   own cards are. Because nothing interactive is ever inside an anchor here,
   no preventDefault()/stopPropagation() call is needed anywhere.

   Every .bcard*/.bpick*/.bmod*/.cartbar*/.cartsheet* rule below is carried
   over from build.html's own <style> block verbatim (values unchanged) —
   see that file's own comments on each for the full history/rationale;
   not re-derived here so the two pages can never quietly drift apart on
   what "added"/"owned"/a module row/the floating cart bar actually look
   like. */
.cc-link{display:flex;flex-direction:column;flex:1;color:inherit;text-decoration:none}
.cc-actions{padding:0 18px 18px}

.bcard{position:relative}
.bcard.owned{opacity:.6}
.bcard.owned .cc-thumb{filter:grayscale(.5)}
.bcard.added{border-color:var(--brand)}
.bcard-actions{margin-top:12px;display:flex;flex-direction:column;gap:8px}
.bt-label{vertical-align:middle}
.ic-chev{width:13px;height:13px;margin-inline-start:4px;transition:transform .2s}
[aria-expanded="true"] .ic-chev{transform:rotate(180deg)}
.b-owned-note{font-size:11.5px;color:var(--text3);margin:8px 0 0}
.b-free-block{margin-top:10px}
.b-free-note{font-size:11.5px;font-weight:600;color:var(--accent);margin:0 0 6px}

.bpick{display:flex;flex-direction:column;gap:6px;margin:8px 0 2px;padding:9px 10px;border:1px solid var(--stroke);border-radius:var(--r-sm);background:var(--glass)}
.bpick-row{display:flex;align-items:center;gap:8px;font-size:11.5px;cursor:pointer}
.bpick-row input{accent-color:var(--brand);flex:none}
.bpick-label{flex:1;display:flex;align-items:center;gap:5px;min-width:0}
.bpick-label .ic{width:14px;height:14px;flex:none}
.bpick-price{flex:none;color:var(--text2);font-size:11px}

.bmodwrap{margin-top:10px}
.bmod-grid{display:flex;flex-direction:column;gap:6px;max-height:250px;overflow:auto;padding-right:2px;margin-bottom:8px}
.bmod-row{display:flex;align-items:center;gap:9px;padding:8px 10px;border:1px solid var(--stroke);border-radius:var(--r-sm);font-size:11.5px;cursor:pointer}
.bmod-row:hover{border-color:var(--stroke-hi)}
.bmod-row.on{border-color:var(--brand);background:rgba(37,112,183,.08)}
.bmod-row input{accent-color:var(--brand);flex:none;width:14px;height:14px}
.bmod-row.owned{cursor:default;opacity:.62}
.bmod-name{flex:1;min-width:0;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bmod-price{flex:none}
.bmod-badge{flex:none;font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.04em}
.bmod-trial{flex:none;font-size:10px;font-weight:700;color:var(--accent)}
.bmod-loading,.bmod-note{padding:12px 4px;text-align:center;color:var(--text3);font-size:12px}

.bcard.legacy .cc-body{opacity:.85}

/* floating cart bar */
/* R157: was background:var(--paper) — identical to the page's own background
   in both themes, so the bar read as part of the page rather than a floating
   element. Darkened relative to --paper so it's visibly distinct in both
   light and dark mode. */
.cartbar{position:fixed;left:0;right:0;bottom:0;z-index:60;background:color-mix(in srgb,var(--paper) 80%,black 20%);border-top:1px solid var(--stroke);box-shadow:0 -8px 24px rgba(0,0,0,.10)}
.cartbar[hidden]{display:none}
.cartbar-inner{max-width:1280px;margin:0 auto;padding:12px 5%;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.cartbar-icon{flex:none;color:var(--brand);display:flex}
.cartbar-icon .ic{width:22px;height:22px}
.cartbar-icon .ic .ib{fill:currentColor;opacity:.20}
.cartbar-icon .ic .is{fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
#cartCount{font-weight:700;font-size:13px}
.cartbar-total{margin-inline-end:auto;font-family:var(--fm);font-size:14px}
.is-disabled{pointer-events:none;opacity:.5}

.cartlayer{position:fixed;inset:0;z-index:70;background:rgba(10,14,20,.45);display:flex;align-items:flex-end;justify-content:center}
.cartlayer[hidden]{display:none}
@media(min-width:620px){.cartlayer{align-items:center}}
.cartsheet{width:100%;max-width:480px;max-height:82vh;display:flex;flex-direction:column;background:color-mix(in srgb,var(--paper) 80%,black 20%);border:1px solid var(--stroke);border-radius:var(--r-obj) var(--r-obj) 0 0;box-shadow:var(--shadow)}
@media(min-width:620px){.cartsheet{border-radius:var(--r-obj)}}
.cartsheet-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--stroke)}
.cartsheet-head h3{margin:0;font-size:15px}
.cartsheet-body{overflow:auto;padding:6px 10px}
.cartline{display:flex;align-items:center;gap:10px;padding:10px 8px;border-bottom:1px solid var(--stroke)}
.cartline:last-child{border-bottom:none}
.cartline-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.cartline-info b{font-size:12.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cartline-remove{flex:none;width:26px;height:26px;font-size:15px;line-height:1}
.cartsheet-foot{display:flex;align-items:center;justify-content:space-between;padding:12px 18px;border-top:1px solid var(--stroke);font-weight:700}
.cartsheet-cta{padding:0 18px 16px}

/* ═══ Task #61 — THE COACH-MARK GUIDED TOUR, ported to the Catalog ═════════
   Byte-for-byte the same .coach-mask/.coach-ring/.coach-tip/.coach-close/
   .coach-kicker/.coach-title/.coach-text/.coach-progress/.coach-nav rules
   every earlier port (student.html, flashcards.html, qbank.html,
   messages.html) uses — see student.html's own big comment above
   .coach-mask for the full design rationale (real spotlights on real
   elements, a 4-piece dark mask with a genuine hole so whatever is
   highlighted stays clickable). This page has no sidebar and no tabs to
   switch, so its JS (catTourOpen() near the end of this file) is the
   simplest of the four ports — no ensureSidebar(), no prepareStep(). */
.coach-mask{
  position:fixed; top:0; left:0; width:0; height:0; z-index:300;
  background:rgba(10,14,20,.55); opacity:0; pointer-events:none;
  transition:top .25s cubic-bezier(.2,.7,.3,1),left .25s cubic-bezier(.2,.7,.3,1),
             width .25s cubic-bezier(.2,.7,.3,1),height .25s cubic-bezier(.2,.7,.3,1),
             opacity .2s;
}
.coach-mask.show{opacity:1;pointer-events:auto}
.coach-ring{
  position:fixed; top:0; left:0; width:0; height:0; z-index:301;
  border-radius:10px; box-shadow:0 0 0 3px var(--brand),0 0 22px rgba(37,112,183,.45);
  opacity:0; pointer-events:none;
  transition:top .25s cubic-bezier(.2,.7,.3,1),left .25s cubic-bezier(.2,.7,.3,1),
             width .25s cubic-bezier(.2,.7,.3,1),height .25s cubic-bezier(.2,.7,.3,1),
             opacity .2s;
}
.coach-ring.show{opacity:1}
.coach-tip{
  position:fixed; top:0; left:0; z-index:302;
  width:308px; max-width:calc(100vw - 24px); max-height:80vh; overflow:auto;
  background:var(--paper); border:1px solid var(--line,var(--stroke)); border-radius:var(--r-obj);
  box-shadow:var(--shadow); padding:18px 18px 16px;
  opacity:0; pointer-events:none; transform:translateY(6px);
  transition:opacity .2s,transform .2s,top .25s cubic-bezier(.2,.7,.3,1),left .25s cubic-bezier(.2,.7,.3,1);
}
.coach-tip.show{opacity:1;pointer-events:auto;transform:none}
.coach-close{
  position:absolute; top:10px; right:10px; width:26px; height:26px;
  border-radius:50%; border:1px solid var(--line,var(--stroke)); background:var(--surface,var(--glass));
  color:var(--text2); display:flex; align-items:center; justify-content:center;
  cursor:pointer; font-size:14px; line-height:1; padding:0;
}
.coach-close:hover{color:var(--text);border-color:var(--text3)}
.coach-kicker{font-family:var(--fm);font-size:10.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--brand);margin:0 0 8px}
.coach-title{font-family:var(--fd);font-size:15.5px;font-weight:700;margin:0 0 6px}
.coach-text{font-size:13px;line-height:1.6;color:var(--text2);margin:0}
.coach-progress{display:flex;gap:4px;margin:14px 0 14px}
.coach-progress i{flex:1;height:3px;border-radius:2px;background:var(--line,var(--stroke));display:block}
.coach-progress i.on{background:var(--brand)}
.coach-nav{display:flex;align-items:center;gap:8px}
.coach-nav .coach-skip{margin-right:auto;background:none;border:none;color:var(--text3);font-size:12.5px;font-weight:600;cursor:pointer;padding:8px 2px}
.coach-nav .coach-skip:hover{color:var(--text2)}
.coach-nav button.btn{padding:8px 14px;font-size:13px}
@media(prefers-reduced-motion:reduce){.coach-mask,.coach-ring,.coach-tip{transition:none}}

/* ===== v215: academies other than Memorize (js/catalog-3.js, html.acad-cat):
   a department drop-down first, then that department's courses ===== */
html.acad-cat .chips-row,html.acad-cat .cat-head p.u-mt-14px,html.acad-cat #cartBar,html.acad-cat #cartLayer,
html.acad-cat #pnavPlan{display:none !important}
html.acad-cat .cat-tools{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
html.acad-cat .cat-dept{flex:1 1 260px;max-width:420px;min-height:46px;font-size:15px}
html.acad-cat .cat-search{flex:1 1 240px}
.cat-wait{display:none}
html.cat-waiting .cat-wait{display:block;margin:24px 0;padding:22px;border:1px dashed var(--line);border-radius:16px;text-align:center;color:var(--text2)}
html.cat-waiting #grid,html.cat-waiting #empty{display:none !important}
