@import url('https://fonts.googleapis.com/css2?family=Changa+One:ital@0;1&display=swap');

:root{
  --bg-0:#3b82f6;
  --bg-1:#2f74e6;
  --bg-2:#1d56c4;
  --line:rgba(255,255,255,0.2);
  --cyan:#ffffff;
  --cyan-dim:rgba(255,255,255,0.16);
  --gold:#e8b75d;
  --btn-text:#1447c9;
  --text-0:#ffffff;
  --text-1:rgba(255,255,255,0.82);
  --text-2:rgba(255,255,255,0.6);
  --radius:14px;
  --edit-bar-h:38px;   /* height of the admin edit bar; 0 for everyone who never sees it */
  --nav-h:69px;        /* height of the fixed site header */
  --disp:'Space Grotesk', sans-serif;
  --body:'Inter', sans-serif;
  --mono:'IBM Plex Mono', monospace;
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Changa One", sans-serif;
    font-weight: 400;
    font-style: normal;
}
body{
  background:var(--bg-0);
  color:var(--text-0);
  font-family:var(--body);
  line-height:1.6;
  overflow-x:hidden;
}
a{text-decoration:none;color:inherit;}
ul{list-style:none;}
img{max-width:100%;display:block;}
::selection{background:var(--cyan);color:var(--btn-text);}

.wrap{max-width:1180px;margin:0 auto;padding:0 32px;}

a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible{
  outline:2px solid var(--cyan);
  outline-offset:3px;
}

/* ---------- NAV ---------- */
header{
  position:fixed; top:0; left:0; right:0; z-index:100;
  background:rgba(20,60,150,0.55);
  backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
}
nav{
  display:flex; align-items:center; justify-content:space-between;
  padding:18px 32px; max-width:1180px; margin:0 auto;
}
.logo{
  font-family:var(--mono); font-size:15px; color:var(--text-0);
  display:flex; align-items:center; gap:8px;
}
.logo .dot{width:8px;height:8px;border-radius:50%;background:var(--cyan);box-shadow:0 0 10px var(--cyan);}
/* Optional avatar in place of the dot, to the left of the logo text. The size comes from the
   --logo-size custom property so the inline resize slider can drive it live. */
.logo-mark{display:inline-flex; align-items:center; flex-shrink:0;}
.logo-avatar{
  width:var(--logo-size,30px); height:var(--logo-size,30px);
  border-radius:50%; object-fit:cover; display:block;
  border:2px solid #fff; flex-shrink:0;
}
.navlinks{display:flex; gap:36px;}
.navlinks a{
  font-size:14px; color:var(--text-1); position:relative; padding:4px 0;
  transition:color .25s;
}
.navlinks a:hover{color:var(--text-0);}
.navlinks a::after{
  content:""; position:absolute; left:0; bottom:0; width:0; height:1px;
  background:var(--cyan); transition:width .25s;
}
.navlinks a:hover::after{width:100%;}
.navcta{
  font-family:var(--mono); font-size:13px; color:var(--bg-0);
  background:var(--cyan); padding:9px 18px; border-radius:8px;
  transition:transform .2s, box-shadow .2s;
}
.navcta:hover{transform:translateY(-2px); box-shadow:0 8px 24px var(--cyan-dim);}
.navtoggle{display:none; flex-direction:column; gap:5px; background:none; border:none; cursor:pointer;}
.navtoggle span{width:22px; height:2px; background:var(--text-0); transition:transform .25s ease, opacity .2s ease;}
/* Open state folds the three bars into an X: the outer two slide to the middle and cross while
   the middle one fades out. 7px is one bar (2) plus the gap (5) — the distance an outer bar has
   to travel to reach the centre. */
.navtoggle.open span:nth-child(1){transform:translateY(7px) rotate(45deg);}
.navtoggle.open span:nth-child(2){opacity:0;}
.navtoggle.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}
.back-link{font-family:var(--mono); font-size:13px; color:var(--text-1); display:flex; align-items:center; gap:6px;}
.back-link:hover{color:var(--text-0);}

/* ---------- HERO ---------- */
.hero{
  min-height:100vh; display:flex; align-items:center;
  position:relative; padding-top:90px; overflow:hidden;
}
.hero .blob{
  position:absolute; border-radius:50%; z-index:0;
  background:radial-gradient(circle at 35% 35%, rgba(255,255,255,0.22), rgba(255,255,255,0.02) 70%);
  animation:float-blob 14s ease-in-out infinite;
}
.hero .blob-1{ width:520px; height:520px; top:-160px; left:-180px; animation-duration:16s; }
.hero .blob-2{ width:640px; height:640px; top:10%; right:-120px; animation-duration:20s; animation-delay:-4s; }
.hero .blob-3{ width:380px; height:380px; bottom:-140px; right:12%; animation-duration:12s; animation-delay:-8s; }
@keyframes float-blob{
  0%   { transform:translate(0,0) scale(1); }
  33%  { transform:translate(24px,-30px) scale(1.05); }
  66%  { transform:translate(-20px,20px) scale(0.97); }
  100% { transform:translate(0,0) scale(1); }
}
@media (prefers-reduced-motion: reduce){
  .hero .blob, .blob{ animation:none; }
}
.hero .wrap{
  position:relative; z-index:1;
  display:grid; grid-template-columns:1.1fr 0.9fr; gap:60px; align-items:center;
}
.accent-divider{
  display:flex; flex-direction:column; align-items:center; gap:10px; margin-bottom:18px;
}
.accent-divider .dot{width:5px;height:5px;border-radius:50%;background:rgba(255,255,255,0.7);}
.accent-divider .rule{width:1px;height:56px;background:rgba(255,255,255,0.5);}
.eyebrow{
  font-family:var(--mono); font-size:13px; color:var(--cyan);
  display:flex; align-items:center; gap:10px; margin-bottom:22px;
}
.eyebrow .bar{width:32px;height:1px;background:var(--cyan);}
h1.name{
  font-family:var(--disp); font-weight:700; font-size:clamp(40px,6vw,68px);
  line-height:1.05; letter-spacing:-0.02em; margin-bottom:18px;
}
h1.name span{color:var(--cyan);}
.role-line{
  font-family:var(--mono); font-size:17px; color:var(--text-1); margin-bottom:26px;
}
.hero-desc{
  font-size:16px; color:var(--text-1); max-width:480px; margin-bottom:34px;
}
.hero-actions{display:flex; gap:16px; flex-wrap:wrap;}
.btn{
  font-size:14px; font-weight:500; padding:14px 26px; border-radius:9px;
  display:inline-flex; align-items:center; gap:8px; transition:all .25s;
  cursor:pointer; border:none;
}
.btn-primary{background:var(--cyan); color:var(--btn-text);}
.btn-primary:hover{transform:translateY(-3px); box-shadow:0 10px 30px var(--cyan-dim);}
.btn-ghost{border:1px solid var(--line); color:var(--text-0); background:transparent;}
.btn-ghost:hover{border-color:var(--cyan); color:var(--cyan);}

/* hero visual: code-card */
.code-card{
  background:#0d121a; border:1px solid #1e2836; border-radius:var(--radius);
  overflow:hidden; box-shadow:0 30px 60px -20px #00204eaa;
}
.code-card .bar{
  display:flex; align-items:center; gap:8px; padding:12px 16px;
  background:#121926; border-bottom:1px solid #1e2836;
}
.code-card .bar span{width:11px;height:11px;border-radius:50%;}
.code-card .bar .r{background:#ff5f57;}
.code-card .bar .y{background:#febc2e;}
.code-card .bar .g{background:#28c840;}
.code-card .bar .file{
  margin-left:10px; font-family:var(--mono); font-size:12px; color:#5c6b80;
}
.code-card pre{
  padding:22px 20px; font-family:var(--mono); font-size:13px; color:#9aa7b8;
  line-height:1.9; overflow-x:auto;
}
.code-card .k{color:#c792ea;} .code-card .s{color:#e8b75d;} .code-card .f{color:#38e8d4;} .code-card .c{color:#5c6b80;}

.scroll-cue{
  position:absolute; bottom:36px; left:32px; display:flex; align-items:center; gap:10px;
  font-family:var(--mono); font-size:12px; color:var(--text-2);
}
.scroll-cue .line{width:1px;height:34px;background:linear-gradient(var(--text-2),transparent);}

/* ---------- SECTION SHELL ---------- */
section{padding:120px 0;}
/* 64px under a heading was tuned for sections that open onto a grid of cards; above a paragraph it
   read as a hole. 44px is the one gap every section now uses, with .is-tight for the ones whose
   first line is body copy rather than cards. */
.sec-head{margin-bottom:44px; max-width:640px;}
.sec-head.is-tight{margin-bottom:26px;}
/* Centred variant — replaces the per-view inline margins that each picked their own number. */
.sec-head.is-centered{margin-left:auto; margin-right:auto; text-align:center;}
.sec-head.is-centered .sec-tag{justify-content:center;}
.sec-tag{
  font-family:var(--mono); font-size:13px; color:var(--cyan); margin-bottom:12px;
  display:flex; align-items:center; gap:10px;
}
.sec-tag .bar{width:24px;height:1px;background:var(--cyan);}
/* Display type inherits body's 1.6, which at 40px is a 64px line box — a two-line heading opened a
   gap wider than the one under the whole block. Headings set their own leading. */
.sec-title{
  font-family:var(--disp); font-weight:600; font-size:clamp(28px,4vw,40px); letter-spacing:-0.01em;
  line-height:1.18;
}
.sec-sub{color:var(--text-1); margin-top:14px; font-size:15px;}
.alt{background:var(--bg-1); border-top:1px solid var(--line); border-bottom:1px solid var(--line);}

/* ---------- ABOUT ---------- */
.about{background:var(--bg-1); border-top:1px solid var(--line); border-bottom:1px solid var(--line);}
.about .grid{display:grid; grid-template-columns:0.8fr 1.2fr; gap:70px; align-items:start;}
/* The frame is a fixed size; --about-zoom only scales the photo inside it.
   object-fit is `contain`, not `cover`, on purpose: with `cover` the picture is cropped to fill
   the frame *before* the scale applies, so zooming out just shrank an already-cropped photo and
   the hidden edges stayed hidden. With `contain` the whole picture is always the thing being
   scaled — 100% fits it inside the frame, less makes it smaller, more zooms in and crops. */
.about-photo-box{position:relative;}
.about-photo img{
  width:100%; height:100%; object-fit:contain; display:block;
  transform:scale(calc(var(--about-zoom,100%) / 100%)); transform-origin:center;
}
.about-photo{
  aspect-ratio:4/5; border-radius:var(--radius); border:1px solid var(--line);
  background:linear-gradient(160deg,#16202c,#0c1119);
  display:flex; align-items:center; justify-content:center;
  font-family:var(--mono); color:var(--text-2); font-size:13px; position:relative; overflow:hidden;
}
.about-photo::before{
  content:""; position:absolute; inset:0;
  background:radial-gradient(circle at 30% 20%, var(--cyan-dim), transparent 60%);
}
.about-facts{display:grid; grid-template-columns:1fr 1fr; gap:20px; margin-top:32px;}
.fact{
  border:1px solid var(--line); border-radius:10px; padding:16px 18px; background:var(--bg-0);
}
.fact b{display:block; font-family:var(--mono); color:var(--cyan); font-size:13px; margin-bottom:4px;}
.fact span{font-size:13px; color:var(--text-1);}
.about p{color:var(--text-1); margin-bottom:16px; font-size:15.5px;}

/* stats */
/* Flex rather than a fixed 4-column grid: the stats are admin-editable, so a row of 3
   (or 5) should stay centred instead of leaving a hole in the last column. The max-width
   matches what a 4-up grid gives each card, so four stats still fill the row exactly. */
.stats{display:flex; flex-wrap:wrap; justify-content:center; gap:24px; margin-top:56px;}
.stat{
  flex:1 1 220px; max-width:282px;
  text-align:center; border:1px solid var(--line); border-radius:var(--radius);
  padding:32px 16px; background:var(--bg-0);
}
.stat .num{
  font-family:var(--disp); font-size:40px; font-weight:700; color:var(--cyan);
}
.stat .lbl{font-size:13px; color:var(--text-1); margin-top:6px; font-family:var(--mono);}

/* ---------- SERVICES ---------- */
.services-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:24px;}
.service-card{
  border:1px solid var(--line); border-radius:var(--radius); padding:32px 28px;
  background:var(--bg-1); transition:transform .3s, box-shadow .3s;
}
.service-card:hover{transform:translateY(-6px); box-shadow:0 24px 50px -20px #000c;}
.service-icon{
  width:46px;height:46px;border-radius:10px; background:var(--cyan-dim);
  display:flex; align-items:center; justify-content:center; margin-bottom:20px;
  color:var(--cyan); font-family:var(--mono); font-size:18px;
}
.service-card h3{font-family:var(--disp); font-size:19px; margin-bottom:10px;}
.service-card p{color:var(--text-1); font-size:14.5px;}

/* ---------- COURSES ---------- */
.courses-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:24px;}
.course-card{
  display:flex; flex-direction:column; border:1px solid var(--line); border-radius:var(--radius);
  background:var(--bg-1); overflow:hidden; transition:transform .3s, box-shadow .3s;
}
.course-card:hover{transform:translateY(-6px); box-shadow:0 24px 50px -20px #00204eaa;}
.course-top{
  padding:24px 24px 0; display:flex; justify-content:space-between; align-items:flex-start; gap:10px;
}
.course-tags{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
.course-icon{font-size:26px; color:var(--cyan); display:flex;}

/* ---------- COURSE LEVEL + PLAYBOOK BADGE ---------- */
/* A level is the same colour everywhere it appears — the course card, the course hero, the admin
   list — because the colour lives on the lvl-* class the server picks (CourseLevels.ToSlug) and
   every badge reads it from these three custom properties rather than restating the palette.
   Junior green, mid-level yellow, senior red; fresh graduate takes the site's cyan, since it sits
   below junior and reusing junior's green would make the two indistinguishable. */
.lvl-junior{--lvl-bg:rgba(74,222,128,.16); --lvl-line:rgba(74,222,128,.38); --lvl-fg:#8ff0bb;}
.lvl-fresh-graduate{--lvl-bg:rgba(56,189,248,.16); --lvl-line:rgba(56,189,248,.38); --lvl-fg:#9bdcff;}
.lvl-mid-level{--lvl-bg:rgba(250,204,21,.16); --lvl-line:rgba(250,204,21,.4); --lvl-fg:#ffdf8a;}
.lvl-senior{--lvl-bg:rgba(248,113,113,.16); --lvl-line:rgba(248,113,113,.4); --lvl-fg:#ffb3b3;}

/* The fallbacks are the old neutral pill, so a badge without an lvl- class still looks right. */
.course-level, .level-badge{
  display:inline-block; font-family:var(--mono); font-size:11px; padding:4px 10px;
  border-radius:20px; white-space:nowrap;
  background:var(--lvl-bg, rgba(255,255,255,0.14));
  color:var(--lvl-fg, var(--text-0));
  border:1px solid var(--lvl-line, transparent);
}
/* The level also appears as a plain stat in the course hero — same colour, no pill. The second
   selector is only there to outrank `.hero-meta .item b`, which sets its own colour. */
.level-text, .hero-meta .item b.level-text{color:var(--lvl-fg, var(--text-0));}

/* A course names one audience or several, so both badge rows wrap rather than stretch their card. */
.level-badges{display:inline-flex; align-items:center; gap:8px; flex-wrap:wrap;}

.playbook-badge{
  display:inline-block; font-family:var(--mono); font-size:10.5px; letter-spacing:.08em;
  padding:4px 10px; border-radius:20px; white-space:nowrap;
  background:var(--cyan-dim); color:var(--cyan); border:1px solid var(--cyan);
}
/* Same pill as a level chip — same padding, radius, mono size and 1px border — so it reads as part
   of the card's own vocabulary rather than a sticker on top of it. Filled with the deep brand blue
   and lettered in white: a level chip tints itself with its own colour, and this one belongs to the
   site, not to a category. */
.soon-badge{
  display:inline-block; font-family:var(--mono); font-size:11px; letter-spacing:.08em;
  padding:4px 10px; border-radius:20px; white-space:nowrap;
  background:var(--bg-2); color:var(--text-0); border:1px solid rgba(255,255,255,0.38);
}

/* A coming-soon card stays legible — this is still a course being advertised — but drops the two
   things that invite a click: the lift on hover and the full-strength body text. The badge keeps
   its colour, so what's dimmed reads as "not yet" rather than "broken". */
.course-card.is-soon{opacity:.72;}
.course-card.is-soon:hover{transform:none; box-shadow:none;}
.course-card.is-soon .course-icon{color:var(--text-2);}

.course-body{padding:18px 24px 24px; display:flex; flex-direction:column; flex:1;}
.course-body h3{font-family:var(--disp); font-size:19px; margin-bottom:8px;}
.course-body p{color:var(--text-1); font-size:14px; flex:1;}
.course-meta{
  display:flex; gap:14px; margin:16px 0; font-family:var(--mono); font-size:12px; color:var(--text-2);
}
.course-foot{display:flex; align-items:center; justify-content:space-between; margin-top:8px;}
.course-price{font-family:var(--disp); font-weight:700; font-size:20px;}
/* The trailing note only — a descendant rule here also caught the _Price partial's own spans and
   shrank the amount itself to the note's size. */
.course-price .price-term{font-family:var(--mono); font-weight:400; font-size:12px; color:var(--text-2);}
.course-link{
  font-family:var(--mono); font-size:13px; color:var(--text-0); display:inline-flex; align-items:center; gap:6px;
  background:none; border:none; cursor:pointer;
}
.course-link:hover{color:var(--cyan);}

/* ---------- PRICING ---------- */
/* The number of tiers is up to the editor, so the grid sizes itself from a count class the view
   stamps on: the max width caps how far the cards spread, and auto-fit turns that into as many
   columns as fit. One tier stays a single readable card instead of stretching across the section. */
.pricing-grid{
  display:grid; gap:28px; margin:0 auto;
  grid-template-columns:repeat(auto-fit,minmax(var(--tier-min,260px),1fr));
  max-width:var(--tier-max,820px);
}
.pricing-grid.tiers-1{--tier-max:440px;}
.pricing-grid.tiers-2{--tier-max:820px;}
.pricing-grid.tiers-3{--tier-max:1060px;}
.pricing-grid.tiers-many{--tier-max:1160px; --tier-min:240px;}
.price-card{
  border:1px solid var(--line); border-radius:var(--radius); padding:36px 32px;
  background:var(--bg-1); position:relative;
}
.price-card.featured{border-color:var(--cyan); background:var(--bg-2);}
.price-badge{
  position:absolute; top:-13px; right:28px; font-family:var(--mono); font-size:11px;
  background:var(--cyan); color:var(--btn-text); padding:5px 12px; border-radius:20px; font-weight:600;
}
.price-name{font-family:var(--mono); font-size:13px; color:var(--text-1); margin-bottom:10px;}
.price-amount{font-family:var(--disp); font-size:38px; font-weight:700; margin-bottom:6px;}
/* Only the "one-time" note is small. This used to be a plain descendant rule, which also caught
   the spans the _Price partial wraps the amount in and shrank the price itself to 14px. */
.price-amount .price-term{font-family:var(--body); font-size:14px; font-weight:400; color:var(--text-2);}
/* The pre-discount price. Sized off the amount beside it (.5em, matching .cur-unit) so it reads as
   an annotation on the price rather than a second price competing with it. */
.price-was{
  font-size:.5em; font-weight:400; color:var(--text-2);
  text-decoration:line-through; margin-right:.4em;
}
/* What the discount is actually worth. Gold rather than cyan: cyan is the "most popular" badge and
   the primary button, and a saving is information, not the thing being asked for. */
.price-save{
  font-family:var(--mono); font-size:12.5px; color:var(--gold);
  margin:-2px 0 14px; min-height:1em;
}
.price-desc{font-size:14px; color:var(--text-1); margin-bottom:24px;}
.price-features{display:flex; flex-direction:column; gap:12px; margin-bottom:28px;}
.price-features li{display:flex; gap:10px; font-size:14px; color:var(--text-1); list-style:none;}
.price-features li::before{content:"✓"; color:var(--cyan); font-weight:700;}
.price-cta{width:100%; text-align:center; display:block;}

/* ---------- SOCIAL CARDS ("Let's Connect") ---------- */
/* One card per social account, sharing its rows with the footer icons. The brand colour is the
   only thing that varies between them, so it lives in one custom property per brand and every
   other rule reads it — adding a network is one .brand-* block, not a new card style. */
.social-cards{
  display:grid; grid-template-columns:repeat(3,1fr); gap:24px; max-width:960px; margin:0 auto;
}
.social-card{
  position:relative; display:flex; flex-direction:column; align-items:flex-start;
  padding:26px 24px 24px; border:1px solid var(--line); border-radius:var(--radius);
  background:var(--bg-1); overflow:hidden; transition:transform .3s, box-shadow .3s, border-color .3s;
}
/* No coloured cap along the top edge: the icon tile already carries the brand, and the line read
   as a stray rule above the card rather than part of it. */
.social-card:hover{
  transform:translateY(-6px); border-color:var(--brand, var(--cyan));
  box-shadow:0 24px 50px -20px #00204eaa;
}
.social-card-icon{
  width:48px; height:48px; border-radius:12px; display:flex; align-items:center; justify-content:center;
  background:var(--brand, var(--cyan)); color:var(--brand-ink, #fff); margin-bottom:20px;
}
.social-card-name{font-family:var(--disp); font-size:18px; font-weight:600; margin-bottom:6px;}
.social-card-desc{font-size:14px; color:var(--text-1);}
/* The reason to click, in the brand colour so it reads as the card's call to action. */
.social-card-note{margin-top:12px; font-size:13.5px; color:var(--brand-note, var(--cyan));}

/* Brand colours. --brand paints the cap and the icon tile, --brand-ink is what sits on top of it,
   and --brand-note is the same colour raised enough to stay readable on the card background. */
.brand-linkedin{--brand:#0a66c2; --brand-ink:#fff; --brand-note:#8ec9ff;}
.brand-medium{--brand:#111; --brand-ink:#fff; --brand-note:#d8e4f5;}
.brand-github{--brand:#181717; --brand-ink:#fff; --brand-note:#d8e4f5;}
.brand-x{--brand:#000; --brand-ink:#fff; --brand-note:#d8e4f5;}
.brand-email{--brand:#e8b75d; --brand-ink:#1b1b1b; --brand-note:#f0d49a;}
.brand-website{--brand:#ffffff; --brand-ink:#1447c9; --brand-note:#ffffff;}

@media(max-width:900px){
  .social-cards{grid-template-columns:1fr; max-width:420px;}
}

/* ---------- CURRENCY ---------- */
/* Both prices are always in the markup; this is what decides which one is on screen. Pounds are
   the default, so a page renders correctly before any script runs — and stays correct if none
   ever does. site.js puts .cur-mode-usd on <body> when the visitor picks dollars.

   The mode class on <body> is deliberately NOT the same name as the class on the price span:
   .cur-usd{display:none} would otherwise match the body itself and hide the entire page. */
.cur-usd{display:none;}
body.cur-mode-usd .cur-egp{display:none;}
body.cur-mode-usd .cur-usd{display:inline;}
/* The unit is deliberately smaller and lighter than the amount: the number is the information. */
.cur-unit{font-family:var(--mono); font-size:.5em; font-weight:400; color:var(--text-2);}
/* "EGP" trails the number and wants a gap; "$" leads it and must not — "$ 129" reads as a typo.
   Keyed off a class, not :first-child, which counts elements only and so matched both. */
.cur-unit-after{margin-left:.3em;}
.cur-unit-before{margin-right:.06em;}

/* For text that only exists to be read aloud — the discounted price renders "2,500 2,000" on
   screen, which is unambiguous visually (one is struck through) and meaningless in a screen
   reader without a word between them. Clipped rather than display:none, which would take it out
   of the accessibility tree along with the layout. */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

.currency-switch{
  display:inline-flex; gap:2px; margin:0 auto 26px; padding:3px;
  border:1px solid var(--line); border-radius:22px; background:var(--bg-1);
}
/* The section is centred, so the switch has to be told to centre too. */
.pricing-grid + .currency-switch, .currency-switch{align-self:center;}
#currencySwitch{display:flex; width:max-content; margin-left:auto; margin-right:auto;}
.currency-option{
  font-family:var(--mono); font-size:12px; letter-spacing:.04em; padding:7px 18px;
  border:none; border-radius:20px; background:none; color:var(--text-2); cursor:pointer;
  transition:background .2s, color .2s;
}
.currency-option[aria-pressed="true"]{background:var(--cyan); color:var(--btn-text);}
.currency-option:hover[aria-pressed="false"]{color:var(--text-0);}

/* Sits under the switch and explains it. Narrow and centred so it reads as a caption on the
   control rather than as body copy belonging to the section. */
.currency-note{
  max-width:420px; margin:-14px auto 30px; text-align:center;
  font-size:13px; color:var(--text-2); line-height:1.5;
}

/* ---------- TESTIMONIALS ---------- */
.testi-slider{position:relative; max-width:720px; margin:0 auto; text-align:center;}
.testi-slide{display:none;}
.testi-slide.active{display:block; animation:fade .5s ease;}
.testi-stars{display:flex; justify-content:center; gap:5px; margin-bottom:18px; color:#ffd166; font-size:18px; letter-spacing:2px;}
/* The unearned stars in a rating below five. Dimmed rather than hidden — the row has to read as
   "3 out of 5", and three gold stars with nothing beside them reads as "3 out of 3". */
.testi-stars .off{color:var(--text-2); opacity:.35;}
@keyframes fade{from{opacity:0; transform:translateY(8px);} to{opacity:1; transform:translateY(0);}}
.testi-quote{
  font-family:var(--disp); font-size:22px; line-height:1.5; color:var(--text-0); margin-bottom:28px;
}
.testi-person{display:flex; flex-direction:column; align-items:center; gap:4px;}
.testi-avatar{
  width:52px;height:52px;border-radius:50%; margin-bottom:10px;
  background:linear-gradient(135deg,var(--cyan),#1c8a80);
  display:flex;align-items:center;justify-content:center; font-family:var(--mono); font-weight:600; color:var(--btn-text);
}
.testi-name{font-weight:600;}
.testi-role{font-size:13px; color:var(--text-1); font-family:var(--mono);}
.testi-dots{display:flex; justify-content:center; gap:8px; margin-top:34px;}
.testi-dot{width:8px;height:8px;border-radius:50%; background:var(--line); cursor:pointer; border:none; transition:background .2s;}
.testi-dot.active{background:var(--cyan);}

/* ---------- CONTACT ---------- */
.contact .grid{display:grid; grid-template-columns:0.9fr 1.1fr; gap:60px;}
.contact-info{display:flex; flex-direction:column; gap:24px;}
.info-item{border:1px solid var(--line); border-radius:12px; padding:20px 22px; background:var(--bg-1);}
.info-item b{display:block; font-family:var(--mono); font-size:12px; color:var(--cyan); margin-bottom:6px; letter-spacing:.04em;}
.info-item span{font-size:15px;}
form{display:flex; flex-direction:column; gap:16px;}
.form-row{display:grid; grid-template-columns:1fr 1fr; gap:16px;}
input, textarea, select{
  width:100%; background:var(--bg-1); border:1px solid var(--line); border-radius:9px;
  padding:14px 16px; color:var(--text-0); font-family:var(--body); font-size:14px;
  transition:border-color .2s;
}
input::placeholder, textarea::placeholder{color:var(--text-2);}
input:focus, textarea:focus, select:focus{border-color:var(--cyan);}
textarea{resize:vertical; min-height:130px;}
.submit-btn{
  align-self:flex-start; background:var(--cyan); color:var(--btn-text); font-weight:600;
  padding:14px 30px; border:none; border-radius:9px; cursor:pointer; font-size:14px;
  transition:transform .2s, box-shadow .2s;
}
.submit-btn:hover{transform:translateY(-3px); box-shadow:0 10px 30px var(--cyan-dim);}
.form-note{font-size:12px; color:var(--text-2); font-family:var(--mono);}
/* Contact picks up .alt (bg-1) when the testimonials section above it is present, which would
   otherwise flatten its cards/inputs — they default to bg-1 too. Drop them to bg-2 so they stay
   readable as raised surfaces either way. */
.contact.alt .info-item,
.contact.alt input,
.contact.alt textarea{background:var(--bg-2);}

/* ---------- FOOTER ---------- */
footer{border-top:1px solid var(--line); padding:36px 0;}
footer .wrap{display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:16px;}
footer .fine{font-size:13px; color:var(--text-2); font-family:var(--mono);}
.social{display:flex; gap:16px;}
.social a{
  width:38px;height:38px; border:1px solid var(--line); border-radius:50%;
  display:flex; align-items:center; justify-content:center; font-family:var(--mono); font-size:12px;
  color:var(--text-1); transition:all .2s;
}
.social a:hover{border-color:var(--cyan); color:var(--cyan); transform:translateY(-3px);}

/* status bar signature */
.statusbar{
  position:fixed; bottom:0; left:0; right:0; z-index:90;
  background:var(--bg-2); border-top:1px solid var(--line);
  font-family:var(--mono); font-size:11.5px; color:var(--text-2);
  display:flex; align-items:center; justify-content:space-between;
  padding:7px 20px;
}
.statusbar .left{display:flex; align-items:center; gap:14px;}
.statusbar .dot{width:7px;height:7px;border-radius:50%; background:var(--cyan);}
.progress-track{position:fixed; top:0; left:0; right:0; height:2px; background:var(--line); z-index:101;}
.progress-bar{height:100%; width:0%; background:var(--cyan); transition:width .1s;}
body{padding-bottom:34px;}

/* scroll-to-top: water-drop reveal */
.scroll-top{
  position:fixed; bottom:78px; right:28px; z-index:96;
  width:50px; height:50px; border:none; cursor:pointer;
  background:var(--cyan); color:var(--btn-text);
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 10px 26px rgba(0,20,60,0.35);
  opacity:0; transform:translateY(46px) scale(0.25);
  border-radius:60% 60% 50% 50% / 70% 70% 40% 40%;
  pointer-events:none;
}
.scroll-top.show{ animation:drop-in .6s cubic-bezier(.34,1.56,.64,1) forwards; pointer-events:auto; }
.scroll-top.hide{ animation:drop-out .45s cubic-bezier(.55,0,.85,.35) forwards; pointer-events:none; }
@keyframes drop-in{
  0%   { opacity:0; transform:translateY(46px) scale(0.25); border-radius:60% 60% 50% 50% / 70% 70% 40% 40%; }
  55%  { opacity:1; transform:translateY(-10px) scale(1.1); border-radius:50%; }
  75%  { transform:translateY(4px) scale(0.96); }
  100% { opacity:1; transform:translateY(0) scale(1); border-radius:50%; }
}
@keyframes drop-out{
  0%   { opacity:1; transform:translateY(0) scale(1); border-radius:50%; }
  35%  { transform:translateY(-6px) scale(1.05); border-radius:55% 55% 45% 45% / 65% 65% 35% 35%; }
  100% { opacity:0; transform:translateY(46px) scale(0.2); border-radius:65% 65% 50% 50% / 75% 75% 30% 30%; }
}
@media (prefers-reduced-motion: reduce){
  .scroll-top.show, .scroll-top.hide{ animation:none; }
  .scroll-top.show{ opacity:1; transform:none; border-radius:50%; pointer-events:auto; }
  .scroll-top.hide{ opacity:0; pointer-events:none; }
}

/* ---------- COURSE DETAIL PAGE ---------- */
/* The header is fixed, so this padding is what keeps the crumb clear of it. The old flat 70px
   left barely a pixel over the navbar's own height — tie it to --nav-h so the gap is a real gap
   and stays correct if the header ever changes height. */
.course-hero{padding:calc(var(--nav-h) + 44px) 0 60px; position:relative; overflow:hidden;}
.blob{position:absolute; border-radius:50%; background:radial-gradient(circle at 35% 35%, rgba(255,255,255,0.2), rgba(255,255,255,0.02) 70%); z-index:0; animation:float-blob 16s ease-in-out infinite;}
.blob-a{width:460px; height:460px; top:-160px; right:-140px;}
.course-hero .wrap{position:relative; z-index:1;}
.crumb{font-family:var(--mono); font-size:12px; color:var(--text-2); margin-bottom:14px;}
/* Shape and colour come from the shared level rules above; this row only places them. */
.hero-badges{display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:16px;}
h1.course-title{font-family:var(--disp); font-size:clamp(30px,4.5vw,46px); font-weight:700; letter-spacing:-0.01em; line-height:1.14; max-width:750px;}
.course-tagline{color:var(--text-1); font-size:16px; max-width:640px; margin-top:14px;}
.hero-meta{display:flex; gap:32px; margin-top:26px; flex-wrap:wrap;}
.hero-meta .item{font-family:var(--mono); font-size:13px; color:var(--text-1);}
.hero-meta .item b{display:block; font-family:var(--disp); font-size:20px; color:var(--text-0);}
/* On the home hero the buttons get their spacing from .hero-desc's margin-bottom, but here they
   follow .hero-meta which has no bottom margin — without this they sit flush against it. */
.course-hero .hero-actions{margin-top:32px;}

/* curriculum accordion */
.module{border:1px solid var(--line); border-radius:12px; margin-bottom:14px; overflow:hidden; background:var(--bg-1);}
.module-head{
  display:flex; align-items:center; justify-content:space-between; padding:20px 24px;
  cursor:pointer; user-select:none;
}
.module-head .left{display:flex; align-items:center; gap:16px;}
.module-num{font-family:var(--mono); font-size:13px; color:var(--text-2);}
.module-head h3{font-family:var(--disp); font-size:17px; font-weight:600;}
.module-head .count{font-family:var(--mono); font-size:12px; color:var(--text-2);}
/* A "+" that rotates 45° into a "×" when the module opens — the same control the FAQ uses, so the
   two accordions on this page behave and read identically. The larger size and the line-height
   keep the glyph optically centred, since "+" sits higher in the em box than the old chevron. */
.module-head .chev{
  transition:transform .25s; color:var(--text-1); font-size:20px; line-height:1; display:block;
}
.module.open .chev{transform:rotate(45deg);}
/* The collapse animates max-height, so the body itself stays padding-free — padding on a box
   clamped to max-height:0 would still show while closed. Every child carries the indent instead,
   which is also what keeps the section summary off the left border. */
.module-lessons{max-height:0; overflow:hidden; transition:max-height .3s ease;}
.module-lessons > ul{padding:0 24px 20px 64px;}
.module-lessons li{font-size:14px; color:var(--text-1); padding:7px 0; border-top:1px solid rgba(255,255,255,0.08);}
.module-lessons li:first-child{border-top:none;}
.module-summary{
  color:var(--text-2); font-size:14px; max-width:720px; padding:0 24px 14px 64px;
}

/* Per-session counts next to a playbook session title — minutes, tasks, files. */
.lesson-meta{color:var(--text-2); font-size:12.5px; margin-left:8px;}

/* outcomes (playbook courses) */
.playbook-summary{color:var(--text-1); font-size:15px; max-width:720px;}
.playbook-objectives{margin-top:18px; display:grid; gap:9px;}
.playbook-objectives li{display:flex; gap:11px; color:var(--text-1); font-size:14.5px;}
.playbook-objectives .tick{color:var(--gold);}
.playbook-access{display:flex; gap:14px; flex-wrap:wrap; align-items:center; margin-top:26px;}
.playbook-access span{color:var(--text-2); font-size:13.5px;}

/* projects */
.projects-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:24px;}
.project-card{border:1px solid var(--line); border-radius:var(--radius); padding:26px; background:var(--bg-1);}
.project-card .tag{font-family:var(--mono); font-size:11px; color:var(--text-2); margin-bottom:12px; display:block;}
.project-card h3{font-family:var(--disp); font-size:18px; margin-bottom:10px;}
.project-card p{font-size:14px; color:var(--text-1);}

/* mentorship */
.mentor-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:24px;}
.mentor-card{text-align:center; padding:30px 22px;}
.mentor-icon{width:50px; height:50px; border-radius:12px; background:var(--cyan-dim); display:flex; align-items:center; justify-content:center; margin:0 auto 18px; color:var(--cyan);}
.mentor-card h3{font-family:var(--disp); font-size:17px; margin-bottom:8px;}
.mentor-card p{font-size:14px; color:var(--text-1);}

/* faq */
.faq-item{border-bottom:1px solid var(--line); padding:22px 0; cursor:pointer;}
.faq-q{display:flex; justify-content:space-between; align-items:center; font-family:var(--disp); font-size:16.5px; font-weight:600;}
.faq-q .chev{transition:transform .25s; color:var(--text-1);}
.faq-item.open .chev{transform:rotate(45deg);}
.faq-a{max-height:0; overflow:hidden; transition:max-height .3s ease; color:var(--text-1); font-size:14.5px;}
.faq-a p{padding-top:14px;}

@media(max-width:900px){
  .hero .wrap, .about .grid, .contact .grid{grid-template-columns:1fr; gap:40px;}
  .stat{flex:1 1 calc(50% - 12px); max-width:none;}
  .services-grid{grid-template-columns:1fr;}
  .courses-grid{grid-template-columns:1fr;}
  .pricing-grid{grid-template-columns:1fr;}
  .form-row{grid-template-columns:1fr;}
  .projects-grid, .mentor-grid{grid-template-columns:1fr;}
  .navlinks{
    position:fixed; top:calc(64px + var(--nav-extra-top, 0px)); right:0; left:0; background:var(--bg-1);
    flex-direction:column; padding:20px 32px; gap:20px; border-bottom:1px solid var(--line);
    transform:translateY(-150%); transition:transform .3s; z-index:99;
  }
  .navlinks.open{transform:translateY(0);}
  .navtoggle{display:flex;}
  .navcta{display:none;}
  body{padding-bottom:40px;}
}

@media(max-width:600px){
  .wrap{padding:0 22px;}
  section{padding:88px 0;}
  .sec-head{margin-bottom:32px;}
  .sec-head.is-tight{margin-bottom:20px;}
  .hero{padding-top:80px;}
  .hero-actions .btn, .btn{width:100%; justify-content:center;}
  .hero-actions{flex-direction:column;}
  .service-card{padding:26px 22px;}
  .course-top{padding:20px 20px 0;}
  .course-body{padding:16px 20px 20px;}
  /* The 64px indent lines the accordion body up under the section title on a wide screen; on a
     phone that is a quarter of the width, so it drops back to the card's own padding. */
  .module-lessons > ul{padding:0 18px 18px 20px;}
  .module-summary{padding:0 18px 12px 20px;}
  .module-head{padding:18px 18px;}
  .hero-meta{gap:20px;}
  .stats{gap:14px;}
  .stat{flex:1 1 calc(50% - 7px); max-width:none; padding:24px 12px;}
  .stat .num{font-size:32px;}
  .price-card{padding:28px 22px;}
  .scroll-top{right:18px; bottom:70px;}
  .statusbar{font-size:10px; padding:6px 14px; gap:8px;}
  .statusbar .left{gap:8px;}
}

/* ---------- INLINE EDIT MODE (public pages, admin only) ---------- */
.edit-toolbar{
  position:fixed; top:0; left:0; right:0; z-index:120; display:flex; align-items:center; gap:12px;
  justify-content:flex-end; padding:8px 20px; background:var(--bg-2);
  border-bottom:1px solid var(--line); font-family:var(--mono); font-size:12.5px;
  height:var(--edit-bar-h); box-sizing:border-box;
}
.edit-toolbar-label{margin-right:auto; color:var(--cyan);}
.edit-toolbar-btn{
  border:1px solid var(--line); border-radius:7px; padding:5px 12px; color:var(--text-0);
  transition:border-color .2s, color .2s;
}
.edit-toolbar-btn:hover{border-color:var(--cyan); color:var(--cyan);}
/* The site header is itself position:fixed at top:0, so the bar has to push it down rather than
   sit over it. Both offsets key off has-edit-toolbar, since the bar is on screen for any signed-in
   admin — not just while editing. */
.has-edit-toolbar{padding-top:var(--edit-bar-h); --nav-extra-top:var(--edit-bar-h);}
.has-edit-toolbar header{top:var(--edit-bar-h);}
.has-edit-toolbar .progress-track{top:var(--edit-bar-h);}

/* Editable regions get a dashed hint on hover; the pencil only appears when you're over it so
   the page still reads like the real site while you scan it. */
.edit-mode .editable, .edit-mode .editable-item{position:relative;}
/* Controls are drawn just outside their element's box (pencils at the corner, the resize popover
   below it). Anything that clips its overflow — the portrait, course cards, curriculum modules —
   would hide them completely, so lift the clip while editing and move the rounding that clip was
   providing onto the children that actually needed it. */
.edit-mode .editable,
.edit-mode .editable-item,
.edit-mode .editable-list{overflow:visible;}
/* Lesson rows live inside the curriculum accordion. It has to keep clipping while collapsed for
   the open/close animation, but once open its max-height equals the content so letting overflow
   through changes nothing visually — and stops the row controls being cut off. */
.edit-mode .module.open .module-lessons{overflow:visible;}
.edit-mode .module-lessons li{padding-right:70px;}
.edit-mode .module-lessons li > .edit-item-tools{top:50%; right:6px; transform:translateY(-50%);}
.edit-mode .editable:hover, .edit-mode .editable-item:hover{outline:1px dashed var(--cyan); outline-offset:4px;}
.edit-mode .editable-list{position:relative;}

.edit-pencil{
  opacity:0; position:absolute; top:-10px; right:-10px; z-index:60;
  width:26px; height:26px; border-radius:50%; border:1px solid var(--line);
  background:var(--bg-2); color:var(--cyan); cursor:pointer; font-size:13px; line-height:1;
  display:inline-flex; align-items:center; justify-content:center; transition:opacity .15s, transform .15s;
}
.edit-item-tools{position:absolute; top:-10px; right:-10px; display:flex; gap:6px; z-index:60;}
.edit-item-tools .edit-pencil{position:static;}
.edit-delete{color:#ff8a8a;}
.edit-mode .editable:hover > .edit-pencil,
.edit-mode .editable:hover > .edit-item-tools .edit-pencil,
.edit-mode .editable-item:hover > .edit-item-tools .edit-pencil{opacity:1;}
.edit-pencil:hover{transform:scale(1.12); border-color:var(--cyan);}

.edit-add{
  display:inline-flex; align-items:center; justify-content:center; cursor:pointer;
  width:38px; height:38px; border-radius:50%; font-size:20px; line-height:1;
  border:1px dashed var(--cyan); background:transparent; color:var(--cyan);
  transition:background .2s;
}
.edit-add:hover{background:var(--cyan-dim);}

.edit-input{
  width:100%; min-width:220px; background:var(--bg-2); border:1px solid var(--cyan);
  border-radius:8px; padding:8px 10px; color:var(--text-0); font:inherit;
}
textarea.edit-input{min-height:110px; resize:vertical;}
.edit-actions{display:inline-flex; gap:8px; margin-top:8px;}
.edit-save, .edit-cancel{
  font-family:var(--mono); font-size:12px; padding:6px 14px; border-radius:7px; cursor:pointer;
  border:1px solid var(--line); background:var(--bg-2); color:var(--text-0);
}
.edit-save{background:var(--cyan); color:var(--btn-text); border-color:var(--cyan);}
.edit-save:disabled{opacity:.6; cursor:default;}

/* Resize popover. Anchored to the element it resizes so the live preview stays in view — a
   centred modal would cover the very thing you're adjusting. */
.edit-size-panel{
  position:absolute; top:100%; right:0; margin-top:10px; z-index:70;
  display:flex; align-items:center; gap:10px; white-space:nowrap;
  background:var(--bg-2); border:1px solid var(--cyan); border-radius:10px; padding:10px 14px;
  box-shadow:0 10px 28px rgba(0,0,0,.35);
}
.edit-size-panel input[type=range]{width:150px; padding:0; background:none; border:none;}
.edit-size-value{
  font-family:var(--mono); font-size:12px; color:var(--cyan); min-width:32px; text-align:right;
}
.edit-size-btn{font-size:12px;}

/* Button-label popover. Same anchoring as the resize control, and for the same reason a button
   cannot be edited in place: the in-place editor's input is full-width, which a pill-shaped .btn
   either bursts or clips. */
.edit-label-panel{
  position:absolute; top:100%; right:0; margin-top:10px; z-index:70;
  display:flex; align-items:center; gap:8px; white-space:nowrap;
  background:var(--bg-2); border:1px solid var(--cyan); border-radius:10px; padding:10px 14px;
  box-shadow:0 10px 28px rgba(0,0,0,.35);
  /* The button's own typography would follow into the box — a centred, uppercase, letter-spaced
     input is unreadable while typing. */
  text-align:left; text-transform:none; letter-spacing:normal;
}
.edit-label-panel .edit-input{width:280px; min-width:0; max-width:60vw;}

.edit-dialog-overlay{
  position:fixed; inset:0; z-index:200; background:rgba(0,0,0,.55);
  display:flex; align-items:center; justify-content:center; padding:20px;
}
.edit-dialog{
  width:100%; max-width:440px; background:var(--bg-1); border:1px solid var(--line);
  border-radius:var(--radius); padding:26px; max-height:90vh; overflow-y:auto;
}
.edit-dialog h3{font-family:var(--disp); font-size:18px; margin-bottom:18px;}
.edit-dialog-field{margin-bottom:16px;}
.edit-dialog-field label{display:block; font-family:var(--mono); font-size:12px; color:var(--text-1); margin-bottom:6px;}
.edit-dialog-field input, .edit-dialog-field textarea, .edit-dialog-field select{background:var(--bg-2);}
.edit-dialog-actions{display:flex; justify-content:flex-end; gap:10px; margin-top:22px;}

.edit-toast{
  position:fixed; bottom:52px; left:50%; transform:translate(-50%, 14px); z-index:220;
  background:var(--cyan); color:var(--btn-text); font-family:var(--mono); font-size:12.5px;
  padding:10px 20px; border-radius:8px; opacity:0; pointer-events:none; transition:opacity .2s, transform .2s;
}
.edit-toast.error{background:#ff8a8a; color:#2a0b0b;}
.edit-toast.show{opacity:1; transform:translate(-50%, 0);}

/* The slider normally shows one testimonial at a time, which would leave the rest unreachable.
   In edit mode they stack so every one can be opened, and the dots stop being meaningful. */
.edit-mode .testi-slide{display:block; margin-bottom:36px; padding-bottom:36px; border-bottom:1px solid var(--line);}
.edit-mode .testi-dots{display:none;}
/* The + row inherits the feature list's check marker otherwise. */
.edit-add-row{list-style:none;}
.edit-add-row::before{content:none !important;}

/* A section switched off for this course. It only ever renders while editing, dimmed and struck
   through the middle, so it reads clearly as "not on the live page" but stays clickable. */
.section-hidden{opacity:.4; position:relative;}
.section-hidden::after{
  content:"HIDDEN ON THIS COURSE"; position:absolute; top:14px; left:50%; transform:translateX(-50%);
  font-family:var(--mono); font-size:11px; letter-spacing:.08em; color:var(--text-0);
  background:rgba(0,0,0,.45); padding:4px 12px; border-radius:20px;
}
.edit-section-toggle{
  display:block; margin:26px auto 0; cursor:pointer; font-family:var(--mono); font-size:12px;
  padding:8px 18px; border-radius:8px; background:transparent; color:var(--text-0);
  border:1px dashed var(--line); transition:border-color .2s, color .2s;
}
.edit-section-toggle:hover{border-color:var(--cyan); color:var(--cyan);}

/* Draft/live state of a course, shown to admins only (visitors never reach a draft page). */
.draft-banner{
  /* Admin chrome, so it floats centred just under the header instead of taking layout space —
     the page below stays exactly where a visitor would see it. */
  position:fixed; left:50%; transform:translateX(-50%);
  top:calc(var(--edit-bar-h) + var(--nav-h) + 12px); z-index:95;
  display:flex; align-items:center; justify-content:center; gap:18px; flex-wrap:wrap;
  padding:10px 20px; max-width:calc(100% - 32px);
  background:var(--gold); color:#3a2a05; border-radius:999px;
  font-family:var(--mono); font-size:12.5px; box-shadow:0 8px 26px rgba(0,0,0,.28);
}
/* Opaque, so page content never shows through it while scrolling past. */
.draft-banner.is-live{background:var(--bg-2); color:var(--text-0); border:1px solid var(--line);}
.draft-banner form{display:inline; gap:0;}
.draft-banner-btn{
  cursor:pointer; font-family:var(--mono); font-size:12px; padding:7px 16px; border-radius:7px;
  border:1px solid currentColor; background:transparent; color:inherit; white-space:nowrap;
}
.draft-banner-btn:hover{background:rgba(0,0,0,0.12);}

/* ---------- ADMIN AREA ---------- */
.admin-shell{min-height:100vh; background:var(--bg-2); padding-bottom:60px;}
.admin-topbar{
  background:rgba(20,60,150,0.55); backdrop-filter:blur(14px); border-bottom:1px solid var(--line);
  padding:16px 32px; display:flex; align-items:center; justify-content:space-between;
}
.admin-topbar .logo{font-family:var(--mono); font-size:15px; display:flex; align-items:center; gap:8px;}
.admin-nav{display:flex; gap:22px; flex-wrap:wrap;}
.admin-nav a{font-size:14px; color:var(--text-1); font-family:var(--mono);}
.admin-nav a:hover{color:var(--text-0);}
.admin-body{max-width:1000px; margin:0 auto; padding:48px 32px;}
.admin-card{border:1px solid var(--line); border-radius:var(--radius); background:var(--bg-1); padding:32px; margin-bottom:24px;}
.admin-title{font-family:var(--disp); font-weight:600; font-size:26px; margin-bottom:24px;}
.admin-table{width:100%; border-collapse:collapse;}
.admin-table th, .admin-table td{text-align:left; padding:12px 10px; border-bottom:1px solid var(--line); font-size:14px;}
.admin-table th{font-family:var(--mono); font-size:12px; color:var(--text-2); text-transform:uppercase;}
.admin-table td.actions{white-space:nowrap; text-align:right;}
.admin-table td.actions a, .admin-table td.actions button{font-family:var(--mono); font-size:12.5px; margin-left:12px; background:none; border:none; color:var(--cyan); cursor:pointer;}
.admin-table td.actions .danger{color:#ff8a8a;}
.form-group{margin-bottom:20px;}
.form-group label{display:block; font-family:var(--mono); font-size:12.5px; color:var(--text-1); margin-bottom:8px;}
.form-group .hint{font-size:12px; color:var(--text-2); margin-top:6px;}
.form-check{display:flex; align-items:center; gap:10px; margin-bottom:20px;}
.form-check input{width:auto;}
.validation-summary-errors{background:rgba(255,90,90,.12); border:1px solid rgba(255,90,90,.4); border-radius:9px; padding:14px 18px; margin-bottom:20px; color:#ffb3b3; font-size:13.5px;}
.validation-summary-errors ul{list-style:disc; padding-left:20px;}
/* The validation-summary tag helper still emits the div (with an empty list) when there are no
   errors — it only tags it as -valid. Without this it renders as an empty red box. */
.validation-summary-valid{display:none;}
.field-validation-error{color:#ffb3b3; font-size:12.5px; display:block; margin-top:6px;}
.input-validation-error{border-color:#ff8a8a !important;}
/* ---------- ADMIN DASHBOARD ---------- */
.dash-stats{display:grid; grid-template-columns:repeat(4,1fr); gap:14px;}
.dash-stat{
  border:1px solid var(--line); border-radius:12px; padding:20px 16px;
  background:var(--bg-2); text-align:center;
}
.dash-stat b{display:block; font-family:var(--disp); font-size:30px; line-height:1.1;}
.dash-stat span{font-family:var(--mono); font-size:11px; color:var(--text-2); letter-spacing:.06em;}
/* Draft count only stands out when there actually are drafts waiting. */
.dash-stat.is-draft b{color:var(--gold);}
@media (max-width:760px){ .dash-stats{grid-template-columns:repeat(2,1fr);} }

/* ---------- ADMIN REPEATER (replaces the "::" textareas) ---------- */
/* The textarea is kept as the value that actually posts, just moved out of sight. */
.repeater-source{position:absolute; width:1px; height:1px; opacity:0; pointer-events:none;}
.repeater-rows{display:flex; flex-direction:column; gap:14px;}
.repeater-row{border:1px solid var(--line); border-radius:12px; padding:16px 18px; background:var(--bg-2);}
.repeater-row-head{display:flex; align-items:center; justify-content:space-between; margin-bottom:12px;}
.repeater-num{font-family:var(--mono); font-size:11.5px; color:var(--text-2); letter-spacing:.06em;}
.repeater-tools{display:flex; gap:6px;}
.repeater-tool{
  width:26px; height:26px; border-radius:7px; cursor:pointer; line-height:1;
  border:1px solid var(--line); background:transparent; color:var(--text-1); font-size:12px;
}
.repeater-tool:hover:not(:disabled){border-color:var(--cyan); color:var(--cyan);}
.repeater-tool:disabled{opacity:.3; cursor:default;}
.repeater-remove{color:#ff8a8a;}
.repeater-field{margin-bottom:12px;}
.repeater-field:last-child{margin-bottom:0;}
.repeater-field label{display:block; font-family:var(--mono); font-size:11.5px; color:var(--text-2); margin-bottom:6px;}
/* A single-field row reads better as one line: label left, input filling the rest. */
.repeater-row.is-single .repeater-field label{display:none;}
/* A tick box belongs beside its label, not under it. */
.repeater-field.is-check{display:flex; align-items:center; gap:8px;}
.repeater-field.is-check label{margin-bottom:0; order:2;}
.repeater-field.is-check input{width:auto; margin:0; accent-color:var(--cyan);}
.repeater-sub{border-top:1px solid var(--line); padding-top:12px; margin-top:14px;}
.repeater-sub-row{display:flex; gap:8px; align-items:center; margin-bottom:8px;}
.repeater-sub-row input{flex:1;}
.repeater-add{
  margin-top:14px; cursor:pointer; font-family:var(--mono); font-size:12px;
  padding:9px 18px; border-radius:8px; background:transparent; color:var(--cyan);
  border:1px dashed var(--line); transition:border-color .2s;
}
.repeater-add:hover{border-color:var(--cyan);}
.repeater-add-sub{margin-top:4px; padding:6px 14px; font-size:11.5px;}
.repeater-empty{font-size:13px; color:var(--text-2); font-family:var(--mono);}

.badge-published{font-family:var(--mono); font-size:11px; padding:3px 9px; border-radius:20px; background:rgba(255,255,255,0.14);}
.badge-draft{font-family:var(--mono); font-size:11px; padding:3px 9px; border-radius:20px; background:rgba(255,90,90,.18); color:#ffb3b3;}
/* The irreversible action on a page, kept visually apart from the rest so it is never clicked by
   momentum on the way down. */
.danger-zone{border-color:rgba(248,113,113,.45); background:rgba(248,113,113,.06);}
.btn-danger{
  border:1px solid rgba(248,113,113,.55); background:rgba(248,113,113,.14); color:#ffb3b3;
}
.btn-danger:hover{background:rgba(248,113,113,.24); border-color:#ffb3b3;}

/* Password reveal / set controls on the student and admin pages. */
.pw-actions{display:grid; gap:14px; margin-top:20px;}
.pw-action{border:1px solid var(--line); border-radius:12px; padding:16px 18px; background:var(--bg-2);}
.pw-action-title{font-family:var(--disp); font-size:14.5px; margin-bottom:10px;}
.pw-action-row{display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-bottom:8px;}
/* The inputs sit inline with their button, so they must not take the full-width admin default. */
.pw-action-row input{width:auto; min-width:170px; flex:0 1 auto; margin:0;}

/* A revealed password. Deliberately loud — it is on screen, and the admin should notice it is. */
.credential-reveal{border-color:var(--gold); background:rgba(232,183,93,.08);}
.credential-value{
  font-family:var(--mono); font-size:18px; color:var(--gold); word-break:break-all;
  display:inline-block; padding:8px 12px; border:1px solid rgba(232,183,93,.4); border-radius:8px;
  background:rgba(0,0,0,.15); user-select:all;
}

/* Pager under a paged admin table. Wraps rather than squashes: on a narrow screen the count drops
   onto its own line above the links instead of colliding with them. */
.pager{
  display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:10px;
  margin-top:16px; padding-top:14px; border-top:1px solid var(--line);
  font-family:var(--mono); font-size:12px; color:var(--text-2);
}
.pager-links{display:flex; align-items:center; gap:14px;}
.pager-links a{color:var(--text-0); border-bottom:1px solid transparent;}
.pager-links a:hover{color:var(--cyan); border-bottom-color:var(--cyan);}
/* The edge of the range keeps its arrow so the control does not change width on the last page. */
.pager-links .is-off{opacity:.35;}
.pager-page{color:var(--text-1);}

/* Checkbox group in the admin form — the course level picker, where several may be ticked. */
.check-row{display:flex; flex-wrap:wrap; gap:10px;}
.check-chip{
  display:inline-flex; align-items:center; gap:8px; cursor:pointer;
  border:1px solid var(--line); border-radius:20px; padding:7px 14px; background:var(--bg-0);
  font-family:var(--mono); font-size:12px;
}
.check-chip input{width:auto; margin:0;}
.check-chip:has(input:checked){border-color:var(--cyan); background:var(--bg-2);}

.admin-actions-row{display:flex; justify-content:space-between; align-items:center; margin-bottom:24px;}
.alert-success{background:rgba(40,200,120,.12); border:1px solid rgba(40,200,120,.4); border-radius:9px; padding:14px 18px; margin-bottom:20px; color:#8ff0bb; font-size:13.5px;}

/* ---------- CURRICULUM FREE / PAID MARKS ---------- */
/* Every lesson row says whether it is included in the free preview or needs the course. Shown on
   the public page precisely because it is a buying signal — a visitor should see what they can
   read today before deciding. */
.module-lessons li.lesson-row{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
}
.lesson-tag{
  font-family:var(--mono); font-size:10px; letter-spacing:.05em; text-transform:uppercase;
  padding:3px 9px; border-radius:20px; flex-shrink:0;
}
.lesson-tag.is-free{
  background:rgba(74,222,128,.16); color:#8ff0bb; border:1px solid rgba(74,222,128,.34);
}
.lesson-tag.is-paid{
  background:rgba(255,255,255,.08); color:var(--text-2); border:1px solid var(--line);
}

/* ---------- AUTH CARD ---------- */
/* Shared by the admin and student sign-in screens so the two look like one product.
   min() rather than a flat max-width: on a narrow phone the card shrinks with the
   viewport instead of forcing horizontal scroll. */
.auth-card{width:min(400px, 100%); margin:0;}
.auth-card input, .auth-card textarea, .auth-card select{max-width:100%;}
.auth-card .form-check input{width:auto;}
@media (max-width:420px){
  .auth-card{padding:24px 20px;}
}
