* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

[hidden] { display: none !important; }

/* Pricing and trial follow the existing warm Codezilla palette. */
.pricing-mode { display:flex; justify-content:center; gap:12px; flex-wrap:wrap; margin:0 0 16px; }
.pricing-mode button { font:inherit; color:var(--dark); background:var(--bg); border:1px solid var(--border); border-radius:var(--radius-sm); padding:12px 24px; cursor:pointer; font-weight:700; }
.pricing-mode button span { display:block; font-size:.85rem; font-weight:400; }
.pricing-mode button[aria-pressed="true"] { background:var(--primary); border-color:var(--primary); }
.pricing-mode button:focus-visible { outline:3px solid var(--orange-deep); outline-offset:3px; }
.pricing-status { text-align:center; color:var(--text); margin-bottom:28px; }
.price-format { font-size:.85rem; font-weight:700; color:var(--orange-deep); margin-bottom:10px; }
.price-installment { color:var(--text); font-size:.9rem; line-height:1.6; margin:16px 0; }
.is-rate-pending .price-amount { font-size:1.5rem; }
.pricing-trial { margin-top:40px; scroll-margin-top:100px; }
.trial-panel { background:var(--bg); border:1px solid var(--border); border-radius:var(--radius); display:grid; grid-template-columns:1.1fr 1fr; gap:48px; padding:42px; align-items:center; }
.trial-panel h2 { color:var(--dark); font-size:2rem; line-height:1.25; margin:14px 0; }
.trial-panel p { color:var(--text); line-height:1.75; margin-bottom:20px; }
.trial-panel .trial-terms { color:var(--orange-deep); font-weight:700; }
.trial-steps { list-style:none; counter-reset:trial; display:grid; gap:22px; }
.trial-steps li { counter-increment:trial; position:relative; padding-left:48px; }
.trial-steps li::before { content:counter(trial); position:absolute; left:0; top:0; width:32px; height:32px; display:grid; place-items:center; background:var(--primary-pale); border-radius:50%; color:var(--dark); font-weight:700; }
.trial-steps strong,.trial-steps span { display:block; }
.trial-steps span { color:var(--text); font-size:.95rem; margin-top:5px; line-height:1.6; }
.registration-options { grid-column:1 / -1; border:1px solid rgba(67,20,7,.25); border-radius:var(--radius-sm); padding:18px; display:grid; grid-template-columns:1fr 1fr; gap:14px; min-width:0; }
.registration-options legend { font-weight:700; padding:0 6px; color:var(--dark); }
.registration-options label { display:block; font-size:.9rem; font-weight:600; color:var(--dark); min-width:0; }
.registration-options select { margin-top:7px; color:var(--dark); background:white; }
.trial-format-note { grid-column:1 / -1; font-size:.9rem; color:var(--dark); line-height:1.6; }
@media(max-width:768px) {
    .trial-panel { grid-template-columns:1fr; padding:26px; gap:28px; }
    .trial-panel h2 { font-size:1.6rem; }
    .registration-options { grid-template-columns:1fr; padding:14px; }
    .pricing-mode button { flex:1; padding:12px 16px; }
}

:root {
    --primary: #fb923c;
    --primary-light: #fdba74;
    --primary-dark: #f97316;
    --primary-pale: #fed7aa;
    --analog-yellow: #fbbf24;
    --analog-yellow-light: #fcd34d;
    --analog-rose: #fb7185;
    --analog-rose-light: #fda4af;
    --dark: #431407;
    --dark-hover: #7c2d12;
    --text: #57534e;
    --text-light: #78716c;
    --text-inverse: #d6d3d1;
    --text-inverse-dim: #a8a29e;
    --bg: #ffffff;
    --bg-alt: #fff7ed;
    --bg-card: #ffffff;
    --border: #f5e6d3;
    --shadow-sm: 0 1px 3px rgba(0,0,0,0.06);
    --shadow: 0 4px 20px rgba(0,0,0,0.08);
    --shadow-lg: 0 10px 40px rgba(249,115,22,0.18);
    --radius: 16px;
    --radius-sm: 10px;

    /* Foreground colours darkened just enough to clear WCAG AA (4.5:1) on their
       own pale backgrounds. The lighter originals below only reach ~2.5:1. */
    --orange-deep: #9a3412;
    --amber-deep: #92400e;
    --rose-cta: #e11d48;
    --rose-cta-hover: #be123c;
    /* Darker still: the success chip needs 3:1 against the orange panel it sits
       on, not just 4.5:1 for its own label. */
    --rose-chip: #9f1239;

    /* RGB triplets, so the warm hues can be reused with an alpha channel
       instead of being re-typed as literal rgba() values. */
    --primary-rgb: 251, 146, 60;
    --analog-yellow-rgb: 251, 191, 36;
    --analog-rose-rgb: 251, 113, 133;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    color: var(--text);
    background: var(--bg);
    line-height: 1.6;
    overflow-x: hidden;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 24px;
}

.navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background: rgba(255,255,255,0.9);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border);
}

.navbar .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 72px;
}

.logo {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 800;
    font-size: 1.4rem;
    color: var(--dark);
    /* An <a class="logo"> on the course pages would otherwise be underlined. */
    text-decoration: none;
}

.logo-icon {
    font-size: 1.6rem;
}

.logo-text {
    color: var(--primary);
}

.nav-menu {
    display: flex;
    list-style: none;
    gap: 36px;
    align-items: center;
}

.nav-menu a {
    text-decoration: none;
    color: var(--text);
    font-weight: 500;
    transition: color 0.2s;
    font-size: 0.95rem;
}

.nav-menu a:hover {
    color: var(--primary);
}

.hamburger {
    display: none;
    flex-direction: column;
    gap: 5px;
    cursor: pointer;
    padding: 8px;
    background: none;
    border: none;
}

.hamburger span {
    width: 24px;
    height: 3px;
    background: var(--dark);
    border-radius: 2px;
    transition: 0.3s;
}

.btn-primary {
    background: var(--primary);
    color: white;
    padding: 10px 22px;
    border-radius: var(--radius-sm);
    border: none;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
    transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
    font-size: 0.95rem;
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
    color: white;
    background: var(--primary-dark);
}

.nav-menu .btn-primary {
    background: var(--rose-cta);
    color: #ffffff;
}

.nav-menu .btn-primary:hover {
    background: var(--rose-cta-hover);
    color: #ffffff;
}

.btn-lg {
    padding: 14px 32px;
    font-size: 1rem;
    border-radius: var(--radius);
}

.btn-secondary {
    background: var(--bg-alt);
    color: var(--dark);
    padding: 14px 32px;
    border-radius: var(--radius);
    border: 2px solid var(--border);
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
    transition: background 0.2s, border-color 0.2s, color 0.2s;
}

.btn-secondary:hover {
    background: white;
    border-color: var(--primary);
    color: var(--primary);
}

.hero {
    padding: 140px 0 80px;
    background: var(--bg-alt);
    position: relative;
    overflow: hidden;
}

.hero::before {
    content: '';
    position: absolute;
    top: -100px;
    right: -100px;
    width: 400px;
    height: 400px;
    background: rgba(var(--analog-rose-rgb), 0.1);
    border-radius: 50%;
}

.hero::after {
    content: '';
    position: absolute;
    bottom: -100px;
    left: -100px;
    width: 500px;
    height: 500px;
    background: rgba(var(--analog-yellow-rgb), 0.1);
    border-radius: 50%;
}

.hero-content {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    gap: 60px;
    align-items: center;
    position: relative;
    z-index: 1;
}

.badge {
    display: inline-block;
    background: rgba(var(--analog-yellow-rgb), 0.18);
    color: var(--amber-deep);
    padding: 6px 16px;
    border-radius: 50px;
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 20px;
}

.hero-text h1 {
    font-size: 3.2rem;
    font-weight: 800;
    color: var(--dark);
    line-height: 1.15;
    margin-bottom: 20px;
}

.text-gradient {
    color: var(--primary);
}

.text-gradient-2 {
    color: var(--analog-rose);
}

.hero-desc {
    font-size: 1.1rem;
    color: var(--text-light);
    margin-bottom: 36px;
    max-width: 520px;
}

.hero-buttons {
    display: flex;
    gap: 16px;
    margin-bottom: 48px;
    flex-wrap: wrap;
}

.hero-stats {
    display: flex;
    gap: 40px;
}

.stat-number {
    font-size: 2rem;
    font-weight: 800;
    color: var(--dark);
}

.stat-label {
    font-size: 0.9rem;
    color: var(--text-light);
    margin-top: 4px;
}

.hero-illustration {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}

.hero-img {
    width: 100%;
    max-width: 640px;
    height: auto;
    object-fit: contain;
}

.section {
    padding: 100px 0;
}

/* The navbar is position:fixed at 72px, so anchor targets would otherwise land
   underneath it and clip the section heading. */
section {
    scroll-margin-top: 72px;
}

.section-header {
    text-align: center;
    max-width: 650px;
    margin: 0 auto 64px;
}

.section-tag {
    display: inline-block;
    background: rgba(var(--primary-rgb), 0.15);
    color: var(--orange-deep);
    padding: 6px 16px;
    border-radius: 50px;
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 16px;
}

.section-header h2 {
    font-size: 2.4rem;
    font-weight: 800;
    color: var(--dark);
    margin-bottom: 16px;
    line-height: 1.2;
}

.section-header p {
    color: var(--text-light);
    font-size: 1.05rem;
}

.tab-buttons {
    display: flex;
    justify-content: center;
    gap: 16px;
    margin-bottom: 56px;
    flex-wrap: wrap;
}

.tab-btn {
    padding: 14px 36px;
    border-radius: 50px;
    border: 2px solid var(--border);
    background: white;
    color: var(--text-light);
    font-size: 1.05rem;
    font-weight: 700;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease,
                transform 0.3s ease, box-shadow 0.3s ease;
}

.tab-btn:hover {
    border-color: var(--primary-light);
    color: var(--primary);
    transform: translateY(-2px);
}

.tab-btn.active {
    background: var(--primary);
    color: white;
    border-color: var(--primary);
    box-shadow: 0 8px 24px rgba(var(--primary-rgb), 0.3);
}

/* Positioning context for the temporary measurement syncPanelHeight() does on
   each panel, so the panel it lifts out of flow stays anchored to this wrapper. */
.tab-panels {
    position: relative;
}

.tab-content {
    display: none;
    animation: fadeIn 0.4s ease;
}

.tab-content.active {
    display: block;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Design has four cards where Coding has three, so a fixed column count squeezed
   them to ~161px of content in the 769-1100px range. auto-fit lets both grids
   degrade on their own terms. */
.courses-grid,
.design-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 28px;
}

.course-card {
    background: var(--bg-card);
    padding: 36px 28px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    transition: transform 0.3s, box-shadow 0.3s, border-color 0.3s;
    position: relative;
    overflow: hidden;
    /* A column flex so .course-cta can claim the slack with `margin-top: auto`
       and sit at the bottom of every card, whatever the description lengths.
       Cards in a grid row all stretch to the tallest, and without this the
       buttons would land at eight different heights. */
    display: flex;
    flex-direction: column;
}

.course-card:hover {
    transform: translateY(-8px);
    box-shadow: var(--shadow-lg);
    border-color: var(--bg-card);
}

.course-card.featured {
    border: 2px solid var(--primary);
    box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.18);
}

.course-card.design-card.featured {
    border-color: var(--analog-rose);
    box-shadow: 0 0 0 4px rgba(var(--analog-rose-rgb), 0.18);
}

.featured-badge {
    position: absolute;
    top: 20px;
    right: 20px;
    background: var(--primary-dark);
    color: white;
    padding: 4px 12px;
    border-radius: 50px;
    font-size: 0.75rem;
    font-weight: 700;
}

.featured-badge.design-badge {
    background: var(--analog-rose);
}

.course-icon {
    width: 64px;
    height: 64px;
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    margin-bottom: 20px;
}

.coding-1 { background: rgba(var(--analog-yellow-rgb), 0.2); }
.coding-2 { background: rgba(var(--primary-rgb), 0.18); }
.coding-3 { background: rgba(var(--analog-rose-rgb), 0.18); }
/* Same rose as .coding-3, just denser. :root only carries three rgb triplets
   and all three are already spent on the first three tiles, so rather than
   invent a fourth hue this reuses one at a higher alpha. That also happens to
   be the useful reading: the four coding tiles run pale-to-dense, and the
   densest one belongs to the most advanced course in the tab. */
.coding-4 { background: rgba(var(--analog-rose-rgb), 0.32); }
.design-1 { background: rgba(252, 211, 77, 0.25); }
.design-2 { background: rgba(var(--primary-rgb), 0.18); }
.design-3 { background: rgba(var(--analog-rose-rgb), 0.18); }
.design-4 { background: rgba(253, 164, 175, 0.25); }

.course-card h3 {
    font-size: 1.4rem;
    color: var(--dark);
    margin-bottom: 8px;
    font-weight: 700;
}

.course-level {
    display: inline-block;
    background: var(--bg-alt);
    color: var(--text-light);
    padding: 4px 12px;
    border-radius: 50px;
    font-size: 0.8rem;
    font-weight: 600;
    margin-bottom: 16px;
    /* Now a flex item, and a column flex stretches its children across the
       cross axis by default. Without this the pill would span the whole card
       instead of hugging "Kelas 1-3 SD". */
    align-self: flex-start;
}

.course-desc {
    color: var(--text-light);
    margin-bottom: 20px;
    font-size: 0.95rem;
}

.course-points {
    list-style: none;
}

.course-points li {
    padding: 6px 0;
    color: var(--text);
    font-size: 0.9rem;
    font-weight: 500;
}

/* Scoped to the card so the ✓ list can be reused on the course pages without
   dragging this spacing along. The margin-top: 0 matters: a bare <ul> carries a
   1em UA margin on both sides, and now that the card is a flex container its
   siblings no longer collapse. Without this reset the gap under the
   description would silently grow from 20px to 36px in all eight cards. */
.course-card > .course-points {
    margin: 0 0 20px;
}

/* The three buttons this project added: one closing each course card, one
   closing each course page back to the catalogue, one closing each price card
   into the registration form. They are the same object at three sizes, so the
   paint lives here once and only the box is set per use. */
.course-cta,
.subpage-back,
.price-cta,
.wa-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-alt);
    color: var(--dark);
    border: 2px solid var(--border);
    border-radius: var(--radius-sm);
    font-weight: 600;
    text-decoration: none;
    transition: background 0.2s, border-color 0.2s, color 0.2s;
}

.course-cta:hover,
.subpage-back:hover,
.price-cta:hover,
.wa-link:hover {
    background: white;
    /* Both the label and the edge take --orange-deep, not --primary. --primary
       is only 2.26:1 on white, so using it for the border would make the
       button's outline all but vanish on hover - 1.4.11 wants 3:1 - on top of
       failing the label. This is deliberate and does not match
       .btn-secondary:hover, which still uses --primary. */
    border-color: var(--orange-deep);
    color: var(--orange-deep);
}

/* Full-width so it reads as the card's floor and gives a bigger target. The
   auto margin is what pins it there when the card is stretched by a taller
   neighbour; the points list above supplies the minimum gap. */
.course-cta {
    margin-top: auto;
    align-self: stretch;
    justify-content: center;
    padding: 11px 20px;
    font-size: 0.9rem;
}

.subpage-back {
    padding: 9px 18px;
    font-size: 0.9rem;
}

/* ---- Registration page ---------------------------------------------------- */

/* Joins the shared button paint above rather than defining its own, so the
   WhatsApp link cannot drift into the 2.26:1 hover that .btn-secondary:hover
   still has. One consistent button on the site. */
.wa-link {
    padding: 11px 20px;
    font-size: 0.9rem;
}

/* The closing call to action on the home page: the orange panel, one button. */
.cta-register {
    position: relative;
    z-index: 1;
    max-width: 600px;
    margin: 0 auto;
    text-align: center;
}

/* .btn-primary inside the orange panel would be orange on orange. The form's
   submit button has always been --dark for the same reason, so this is that
   same treatment scoped to the panel. Scoped rather than global: .btn-primary
   on a white background elsewhere still wants to stay orange. */
.cta-register .btn-primary {
    background: var(--dark);
}

.cta-register .btn-primary:hover {
    background: var(--dark-hover);
}

/* Honeypot for the registration form. Parked off-screen rather than
   display:none, because a bot that only fills visible controls walks straight
   past a hidden one - and .honeypot is absolutely positioned, so it also takes
   no grid cell in .cta-form. */
.honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Swallows the Apps Script reply so the visitor never leaves the page. Kept as a
   real box at zero size instead of display:none so it stays a browsing context
   the form can target. */
.hidden-frame {
    position: absolute;
    width: 0;
    height: 0;
    border: 0;
    visibility: hidden;
}

.daftar-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 28px;
    color: var(--text-light);
    font-size: 0.95rem;
}

.daftar-actions a {
    color: var(--orange-deep);
    font-weight: 600;
}

/* Same colour as the text beside it rather than --border. As a border colour it
   measured 1.23:1 on white, which is invisible, and a separator you cannot see
   does not separate anything. */
.daftar-actions-sep {
    color: var(--text-light);
}

/* Inside the rose success chip: white on --rose-chip is about 8:1, so a plain
   underlined link stays well clear rather than borrowing the orange buttons,
   which are unreadable against that panel. */
.form-success p {
    margin-bottom: 10px;
}

.wa-link-inline {
    color: #ffffff;
    font-weight: 700;
    text-decoration: underline;
}

.form-success button {
    margin-top: 6px;
    background: transparent;
    color: #ffffff;
    border: 2px solid rgba(255, 255, 255, 0.6);
    border-radius: var(--radius-sm);
    padding: 10px 20px;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}

.form-success button:hover {
    background: rgba(255, 255, 255, 0.14);
}

/* ---- Price list ---------------------------------------------------------- */

/* Sits between two white sections, so it needs a background of its own or the
   catalogue runs into "Tentang Kami" as one unbroken field. */
.harga-section {
    background: var(--bg-alt);
}

.pricing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 28px;
}

/* Flex column for one reason: the plan rows carry margin-top: auto, which pins
   them and the button below them to the card floor when a neighbouring card is
   taller because it lists more courses. */
.price-card {
    display: flex;
    flex-direction: column;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 28px;
    box-shadow: var(--shadow-sm);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

/* A gentler lift than .course-card's -8px, because these cards are much taller.
   Like .course-card:hover, the shadow does the separating and the border is left
   alone - --primary-pale on white is only 1.35:1, so recolouring it would have
   signalled nothing. The reduced-motion block already forces transition-duration
   to ~0, so nothing moves for anyone who asked for that. */
.price-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow);
}

/* align-self: flex-start, as .course-level needs: without it the chip stretches
   to the full column width and stops reading as a label. */
.price-level {
    align-self: flex-start;
    background: rgba(var(--primary-rgb), 0.15);
    color: var(--orange-deep);
    padding: 4px 14px;
    border-radius: 50px;
    font-size: 0.8rem;
    font-weight: 700;
    margin-bottom: 16px;
}

.price-rate {
    margin-bottom: 22px;
    color: var(--text-light);
    font-size: 0.85rem;
}

.price-amount {
    display: block;
    color: var(--dark);
    font-size: 2.3rem;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.02em;
}

/* The amount is a block, so the unit falls onto its own line underneath it
   without any margin collapse to worry about. */
.price-unit {
    display: block;
    margin-top: 4px;
}

.price-courses-label {
    color: var(--text-light);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-bottom: 10px;
}

.price-courses {
    list-style: none;
    margin-bottom: 22px;
}

.price-courses li {
    position: relative;
    padding-left: 22px;
    margin-bottom: 8px;
    color: var(--text);
    font-size: 0.92rem;
}

.price-courses li::before {
    content: "\2713";
    position: absolute;
    left: 0;
    color: var(--orange-deep);
    font-weight: 700;
}

.price-courses li span {
    color: var(--text-light);
    font-size: 0.85rem;
}

/* Stands in for the course list on the one card that has none, and keeps the
   card's inner rhythm identical so the plan rows still land on the floor. */
.price-empty {
    background: var(--bg-alt);
    border-left: 3px solid var(--primary-pale);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
    margin-bottom: 22px;
    color: var(--text);
    font-size: 0.92rem;
}

/* The one auto margin in the card. The rows above it sit at the top, these sit
   on the floor, and the grid stretches all three cards to the tallest. */
.price-plans {
    margin-top: auto;
    margin-bottom: 18px;
    border-top: 1px solid var(--border);
}

.price-plan {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}

.price-plan:last-child {
    border-bottom: none;
}

.price-plan-name {
    color: var(--text-light);
    font-size: 0.9rem;
}

.price-plan-total {
    color: var(--dark);
    font-size: 1.02rem;
    font-weight: 700;
    white-space: nowrap;
}

/* Bigger than .course-cta on purpose: this is the card's only action, where the
   course CTA is one of three things the card offers. */
.price-cta {
    align-self: stretch;
    justify-content: center;
    padding: 14px 24px;
    font-size: 1rem;
}

/* Two labels for one link. The long one above 480px; the short one below it,
   where the logo and the full text together overflow the viewport. Both live
   in the same <a>, so the accessible name stays one string with no duplicated
   "Materi" for a screen reader to read out twice. */
.subpage-back-long {
    display: inline;
}

.subpage-back-short {
    display: none;
}

/* ---- Course pages (materi/*.html) ----
   Each of the eight pages reuses the catalogue card's icon, level and bullet
   list, so the catalogue and the worked example never drift apart, and only
   the page-specific pieces are declared here. */

.page-hero {
    padding: 140px 0 56px;
    text-align: center;
}

.page-hero .container {
    max-width: 760px;
}

.page-hero h1 {
    font-size: 2.6rem;
    font-weight: 800;
    color: var(--dark);
    line-height: 1.2;
    margin-bottom: 16px;
}

.page-hero > .container > p {
    color: var(--text-light);
    font-size: 1.05rem;
    margin-bottom: 28px;
}

/* A row of facts about the course: how many lessons, how long, what it ends
   with. Flex-wrap so it folds to one column on a phone instead of squashing. */
.page-facts {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    list-style: none;
}

.page-fact {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-alt);
    border: 1px solid var(--border);
    border-radius: 50px;
    padding: 7px 16px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--dark);
}

.page-fact-icon {
    font-size: 1rem;
    line-height: 1;
}

/* Course pages: school level, program, relevant tools, then session details. */
.course-materials .page-hero { background: var(--bg-alt); padding: 120px 0 24px; border-bottom: 1px solid var(--border); }
.course-materials .page-hero .container { max-width: 1000px; }
.course-materials .page-hero h1 { font-size: clamp(1.8rem, 3.8vw, 2.6rem); }
.course-materials .page-hero > .container > p { max-width: 740px; margin: 0 auto 22px; font-size: 1rem; }
.course-materials .page-fact { background: var(--bg-card); }
.course-materials .course-age-tabs { margin: 30px auto 0; gap: 12px; }
.course-materials .course-age-tabs .tab-btn { min-width: 140px; padding: 10px 28px; border-radius: var(--radius-sm); font-size: 0.95rem; border-width: 1px; }
.course-materials .course-age-tabs .tab-btn.active { background: var(--primary-pale); color: var(--orange-deep); border-color: var(--primary); box-shadow: none; }
.course-materials .course-age-tabs .tab-btn:hover { transform: none; }
.course-program-bar { padding: 18px 0 0; background: var(--bg); }
.course-materials .course-program-tabs { margin: 0; gap: 32px; }
.course-materials .course-program-tabs .tab-btn { padding: 10px 12px 12px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--text-light); box-shadow: none; font-size: 1rem; transform: none; }
.course-materials .course-program-tabs .tab-btn.active { color: var(--orange-deep); border-bottom-color: var(--orange-deep); }
.course-materials .course-program-tabs .tab-btn:hover { color: var(--orange-deep); }
.course-materials .course-level-panel { scroll-margin-top: 88px; }
.course-materials .lesson { scroll-margin-top: 92px; }
.course-project-tools { background: var(--bg-alt); border-left: 3px solid var(--primary); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; padding: 12px 16px; font-size: 0.85rem; line-height: 1.7; }
.course-project-tools strong { color: var(--orange-deep); }

.course-tools { padding: 28px 0 44px; background: var(--bg); scroll-margin-top: 92px; }
.course-tools .section-header { margin-bottom: 24px; }
.course-tools .section-header h2 { font-size: 1.85rem; margin-bottom: 12px; }
.course-tools .section-header p { max-width: 650px; margin-inline: auto; font-size: 0.95rem; }
.course-tools-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; max-width: 1000px; margin-inline: auto; }
.course-tools-grid[data-tool-count="1"] { grid-template-columns: 1fr; max-width: 520px; }
.course-tools-grid[data-tool-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 860px; }
.course-tool-card { padding: 22px 24px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); min-width: 0; }
.course-tool-card h3 { color: var(--dark); font-size: 1.05rem; line-height: 1.4; }
.course-tool-name { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.course-tool-access { color: var(--text); font-size: 0.72rem; background: var(--bg-alt); border: 1px solid var(--border); border-radius: 6px; padding: 2px 7px; }
.course-tool-card p { color: var(--text); font-size: 0.9rem; margin: 10px 0 14px; line-height: 1.75; }
.course-tool-card a { display: inline-flex; align-items: center; gap: 7px; color: var(--orange-deep); font-size: 0.85rem; font-weight: 600; text-decoration: none; }
.course-tool-card a:hover { text-decoration: underline; text-underline-offset: 4px; }
.course-session-section { background: var(--bg-alt); padding: 48px 0 64px; border-block: 1px solid var(--border); }
.course-session-section > .container > .section-header { max-width: 860px; margin: 0 auto 28px; }
.course-session-section .section-header h2 { font-size: 2rem; }
.course-session-section .section-header p { font-size: 1rem; }
.course-entry { max-width: 860px; margin: 0 auto 28px; background: var(--bg-card); }
.course-entry p + p { margin-top: 8px; }
.course-session-section .course-path-nav + .lesson-list { margin-top: 28px; }
.course-session-section .path-divider { margin: 40px 0 24px; color: var(--dark); scroll-margin-top: 92px; }

@media (max-width: 760px) {
    .course-materials .page-hero { padding: 108px 0 24px; }
    .course-materials .course-age-tabs { gap: 8px; margin-top: 24px; }
    .course-materials .course-age-tabs .tab-btn { min-width: 0; flex: 1 1 0; max-width: 200px; padding: 10px 12px; }
    .course-materials .course-program-tabs { gap: 24px; }
    .course-tools { padding: 24px 0 32px; }
    .course-tools-grid, .course-tools-grid[data-tool-count="2"] { grid-template-columns: 1fr; gap: 12px; max-width: 520px; }
    .course-tool-card { padding: 20px; }
    .course-tools .section-header h2, .course-session-section .section-header h2 { font-size: 1.6rem; }
    .course-session-section { padding: 36px 0 48px; }
}

.lesson-list {
    max-width: 860px;
    margin: 0 auto;
}

.lesson {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 28px;
    margin-bottom: 20px;
}

/* Same card hover as the catalogue, minus the lift: these are stacked in a
   single column, so moving one up would collide with the one above it. */
.lesson:hover {
    border-color: var(--primary-pale);
    box-shadow: var(--shadow);
}

.lesson-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 16px;
}

.lesson-num {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--primary-pale);
    color: var(--orange-deep);
    font-weight: 700;
    font-size: 0.95rem;
    /* Inherits the global line-height:1.6, which would sit the digit low in
       the circle. */
    line-height: 1;
}

.lesson h2,
.lesson h3 {
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--dark);
    line-height: 1.3;
}

.lesson-body > p {
    color: var(--text);
    margin-bottom: 14px;
}

/* Code the child would actually type. Dark, because this is the one place on
   the page that wants to read as a different medium from the prose around it,
   and it reuses the existing --dark / --text-inverse pair. */
.code-block {
    background: var(--dark);
    color: var(--text-inverse);
    border-radius: var(--radius-sm);
    padding: 18px 20px;
    overflow-x: auto;
    margin-top: 16px;
}

.code-block code {
    font-family: "Consolas", "Monaco", "Courier New", monospace;
    font-size: 0.85rem;
    line-height: 1.7;
    color: inherit;
}

.lesson-note {
    background: var(--bg-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 16px 18px;
    font-size: 0.9rem;
    color: var(--text);
}

.lesson-note strong {
    display: block;
    color: var(--dark);
    margin-bottom: 6px;
}

.course-path-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 28px;
}

.course-prerequisite {
    margin-bottom: 28px;
}

.course-level-panel[hidden] {
    display: none;
}

.project-example {
    margin: 20px 0 0;
}

.project-example img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius-sm);
}

.project-example figcaption {
    margin-top: 10px;
    color: var(--text-light);
    font-size: 0.85rem;
    line-height: 1.6;
}

.page-cta {
    background: var(--bg-alt);
    text-align: center;
    padding: 72px 0;
}

.page-cta h2 {
    font-size: 2.2rem;
    font-weight: 800;
    color: var(--dark);
    margin-bottom: 12px;
}

.page-cta p {
    color: var(--text-light);
    margin-bottom: 28px;
}

.subpage-foot {
    background: var(--dark);
    padding: 28px 0;
    text-align: center;
    color: var(--text-inverse-dim);
    font-size: 0.9rem;
}

.subpage-foot a {
    color: var(--analog-yellow-light);
    text-decoration: none;
}

.subpage-foot a:hover {
    text-decoration: underline;
}

.about-content {
    display: grid;
    grid-template-columns: 1fr 1.2fr;
    gap: 80px;
    align-items: center;
}

.about-illustration {
    display: flex;
    justify-content: center;
}

.kids-box {
    width: 100%;
    max-width: 400px;
    height: 360px;
    background: var(--bg-alt);
    border-radius: 24px;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
}

.kid {
    font-size: 4.5rem;
    animation: bounce 3s ease-in-out infinite;
}

.kid-1 { animation-delay: 0s; }
.kid-2 { animation-delay: 0.5s; font-size: 5.5rem; }
.kid-3 { animation-delay: 1s; }

@keyframes bounce {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-20px); }
}

.about-text h2 {
    font-size: 2.2rem;
    font-weight: 800;
    color: var(--dark);
    margin: 16px 0 20px;
    line-height: 1.2;
}

.about-text > p {
    color: var(--text-light);
    margin-bottom: 32px;
    font-size: 1.05rem;
}

.benefits {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

.benefit-item {
    display: flex;
    gap: 14px;
    padding: 16px;
    border-radius: var(--radius-sm);
    background: var(--bg-alt);
    transition: background 0.2s, box-shadow 0.2s;
}

.benefit-item:hover {
    background: white;
    box-shadow: var(--shadow-sm);
}

.benefit-icon {
    font-size: 1.8rem;
    flex-shrink: 0;
}

.benefit-item h3 {
    color: var(--dark);
    font-weight: 700;
    margin-bottom: 4px;
    font-size: 1rem;
}

.benefit-item p {
    font-size: 0.85rem;
    color: var(--text-light);
}

.cta-section {
    padding: 80px 0;
}

.cta-box {
    background: var(--primary);
    border-radius: 28px;
    padding: 64px;
    color: white;
    position: relative;
    overflow: hidden;
}

.cta-box::before {
    content: '';
    position: absolute;
    top: -100px;
    right: -100px;
    width: 300px;
    height: 300px;
    background: rgba(255,255,255,0.08);
    border-radius: 50%;
}

.cta-box::after {
    content: '';
    position: absolute;
    bottom: -80px;
    left: -80px;
    width: 250px;
    height: 250px;
    background: rgba(255,255,255,0.06);
    border-radius: 50%;
}

.cta-text {
    position: relative;
    z-index: 1;
    text-align: center;
    margin-bottom: 40px;
}

.cta-text h2 {
    font-size: 2.2rem;
    font-weight: 800;
    margin-bottom: 12px;
    line-height: 1.2;
}

.cta-text p {
    opacity: 0.9;
    font-size: 1.05rem;
}

.cta-form {
    position: relative;
    z-index: 1;
    max-width: 600px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

.cta-form input,
.cta-form select {
    padding: 14px 18px;
    border-radius: var(--radius-sm);
    border: none;
    font-size: 0.95rem;
    font-family: inherit;
    transition: box-shadow 0.2s;
    width: 100%;
}

.cta-form button {
    grid-column: 1 / -1;
    background: var(--dark);
    color: white;
    padding: 16px;
    border: none;
    border-radius: var(--radius-sm);
    font-weight: 700;
    font-size: 1rem;
    cursor: pointer;
    transition: background 0.2s, transform 0.2s;
    margin-top: 8px;
}

.cta-form button:hover {
    background: var(--dark-hover);
    transform: translateY(-2px);
}

.form-success {
    position: relative;
    z-index: 1;
    max-width: 600px;
    margin: 32px auto 0;
    background: var(--rose-chip);
    border: 1px solid rgba(255, 255, 255, 0.4);
    color: #ffffff;
    padding: 16px;
    border-radius: var(--radius-sm);
    text-align: center;
    font-weight: 600;
}

.hidden {
    display: none;
}

.footer {
    background: var(--dark);
    color: white;
    padding: 72px 0 0;
}

.footer-content {
    display: grid;
    /* Was 1.5fr 2fr. The Materi block needs ~490px so its coding and design
       lists can sit side by side without cramping "Bitmap Editing" onto two
       lines, so the links side claims more of the row and the brand column
       gives up some width. Its paragraph caps at 360px anyway. */
    grid-template-columns: 1fr 2.4fr;
    gap: 60px;
    padding-bottom: 48px;
}

.footer-brand .logo-text {
    color: var(--primary-light);
}

.footer-brand p {
    margin-top: 16px;
    color: var(--text-inverse);
    max-width: 360px;
    font-size: 0.95rem;
}

.footer-links {
    display: grid;
    /* Materi is wider than Kontak because it carries two sub-columns of course
       names while Kontak carries three short address lines. */
    grid-template-columns: 2fr 1fr;
    gap: 40px;
}

/* The coding and design lists sit side by side under one "Materi" heading, so
   this is a nested grid rather than two columns of their own. */
.footer-materi {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
}

.footer-links h2 {
    font-size: 1rem;
    font-weight: 700;
    margin-bottom: 20px;
    color: var(--bg-alt);
}

/* Coding and design are sub-headings inside the Materi block rather than
   columns of their own, so the split is carried by type instead of position. */
.footer-links h3 {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    /* Same colour .footer-bottom already uses on this background: 6.2:1, so
       it clears AA for text this small. */
    color: var(--text-inverse-dim);
    margin-bottom: 14px;
}

.footer-links ul {
    list-style: none;
}

.footer-links li {
    margin-bottom: 12px;
    font-size: 0.9rem;
    color: var(--text-inverse);
}

.footer-links a {
    color: var(--text-inverse);
    text-decoration: none;
    transition: color 0.2s;
}

.footer-links a:hover {
    color: var(--analog-yellow-light);
}

.footer-bottom {
    border-top: 1px solid var(--dark-hover);
    padding: 24px 0;
    text-align: center;
    color: var(--text-inverse-dim);
    font-size: 0.9rem;
}

@media (max-width: 968px) {
    .hero-content,
    .about-content {
        grid-template-columns: 1fr;
        gap: 48px;
    }

    .hero-text h1 {
        font-size: 2.4rem;
    }

    /* Height is 400px at every breakpoint now, so only the stacking order is
       left to change here. */
    .hero-illustration {
        order: -1;
    }

    .section-header h2,
    .about-text h2,
    .cta-text h2 {
        font-size: 1.8rem;
    }

    .footer-content {
        grid-template-columns: 1fr;
        gap: 40px;
    }

    /* Three price cards stop fitting at about 860px of container width, and
       auto-fit answers that by dropping to two - which would leave a single card
       stranded on its own row. One centred column instead, capped so it does not
       stretch into a banner. */
    .pricing-grid {
        grid-template-columns: 1fr;
        max-width: 480px;
        margin-left: auto;
        margin-right: auto;
    }

    .cta-box {
        padding: 40px 28px;
    }
}

@media (max-width: 768px) {
    .nav-menu {
        display: none;
        position: absolute;
        top: 72px;
        left: 0;
        right: 0;
        background: white;
        flex-direction: column;
        padding: 20px 24px;
        gap: 16px;
        border-bottom: 1px solid var(--border);
        box-shadow: var(--shadow);
    }

    .nav-menu.active {
        display: flex;
    }

    .hamburger {
        display: flex;
    }

    .section {
        padding: 72px 0;
    }

    .hero {
        padding: 120px 0 60px;
    }

    .hero-stats {
        gap: 24px;
    }

    .stat-number {
        font-size: 1.5rem;
    }

    .courses-grid {
        grid-template-columns: 1fr;
    }

    .benefits {
        grid-template-columns: 1fr;
    }

    .cta-form {
        grid-template-columns: 1fr;
    }

    /* Materi takes the full row here rather than sharing it with Kontak, so the
       nested coding/design pair still gets ~348px per sub-column instead of the
       ~158px it would get in a half-width track. */
    .footer-links {
        grid-template-columns: 1fr;
    }

    /* ---- Course pages ---- */
    /* The course title is longer than a hero headline, so it steps down sooner
       than .hero-text h1 does. */
    .page-hero h1 {
        font-size: 2.1rem;
    }

    /* The lesson number and the title sit side by side with a 14px gap; at phone
       width a long Indonesian title wraps to three lines and the number drifts
       up out of alignment. Aligning to the top keeps them lined up. */
    .lesson-head {
        align-items: flex-start;
    }

    .lesson {
        padding: 24px 22px;
    }

    .page-cta h2 {
        font-size: 1.8rem;
    }
}

@media (max-width: 480px) {
    .hero-text h1 {
        font-size: 2rem;
    }

    /* Rp3.040.000 is the widest string in the card and the column is down to
       about 270px of content here, so the rate steps down with the padding. */
    .price-amount {
        font-size: 2rem;
    }

    .price-card {
        padding: 24px 22px;
    }

    .hero-buttons {
        flex-direction: column;
    }

    .btn-primary, .btn-secondary {
        width: 100%;
        text-align: center;
    }

    .footer-links {
        grid-template-columns: 1fr;
    }

    /* Two sub-columns stop fitting comfortably on a phone, so coding and
       design stack instead of squeezing. */
    .footer-materi {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    /* ---- Course pages ---- */
    /* Code is the widest thing on these pages and it must not wrap, so instead
       of shrinking the type the padding gives way and the block keeps its own
       horizontal scroll. */
    .code-block {
        padding: 16px 14px;
        font-size: 0.8rem;
    }

    /* At 320px the logo and the full "Kembali ke Materi" label together
       overflow the 272px of usable width, so the label shortens to "Materi"
       here. The back link still reads as a link, and the icon alone would not
       have been clear enough. */
    .subpage-back {
        padding: 8px 12px;
        font-size: 0.8rem;
    }

    .subpage-back-long {
        display: none;
    }

    .subpage-back-short {
        display: inline;
    }

    /* Three lines of course title pushed the hero facts out of view on a
       small phone. */
    .page-hero h1 {
        font-size: 1.75rem;
    }

    .page-hero {
        padding: 128px 0 44px;
    }
}

/* Scroll-triggered reveal, driven by a .reveal / .is-visible pair from
   script.js. Kept in CSS so the elements are never inline-styled. */
.reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}

.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* A light ring plus a dark ring, so at least one of them always clears 3:1
   against its backdrop - the page spans white cards, an orange panel and a
   dark-brown footer, and no single colour works on all three. */
:focus-visible {
    outline: 2px solid var(--bg);
    outline-offset: 2px;
    box-shadow: 0 0 0 5px var(--dark);
}

/* Six animations on this page run forever. Honour the OS-level request to
   stop, and never leave reveal content stuck at opacity 0. */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .reveal {
        opacity: 1;
        transform: none;
    }

    /* Belt and braces. The global override above already forces
       animation-iteration-count to 1, and every keyframe below ends on its own
       neutral frame, so nothing is left mid-flicker or mid-drift. Nothing else
       is needed: the chips' and tools' static tilt lives in the `rotate`
       property, which is not an animated property, so dropping the animation
       cannot drop the tilt. */
    .hero-img {
        animation: none;
    }
}
