/*
 * Styles for the three public React pages in this directory: homeReact.jsp, registerReact.jsp and
 * passwordResetReact.jsp.
 *
 * Lifted out of users/generalFiles/styles/styles.css, which is ~280 KB loaded by the whole signed-in
 * app. None of it applied anywhere but these three pages, and the pages are the one part of the site
 * whose first-load weight is judged by people who have not signed up yet - so it travels with them
 * instead of with everything else.
 *
 * What stayed behind in styles.css is what is not ours: the HOTmaths brand ramp, which re-points
 * vector's --color-primary-* for every vector page including Checkpoints, and .ch-visually-hidden,
 * which this page set uses but did not introduce.
 */

/* ==========================================================================
   PUBLIC PAGES - homepage, registration and password reset (React, on vector)
   ==========================================================================

   One set of primitives shared by all three pages, not one set per page. An earlier pass had parallel
   ch-home-* and ch-registration-* rules doing the same jobs; anything that differed between them was an
   accident rather than a decision.

   Everything here layers on vector, which the pages load via base.css: its spacing scale (--space-*),
   colour tokens (--color-*) and radii (--radius-*). No literal colours or spacings below - a value vector
   does not have is a signal to add it there, not to invent one here.

   Responsive by construction rather than by breakpoint: grids use auto-fit/minmax and headings use
   clamp(), so there is a single narrow-screen media query at the end for the few things that genuinely
   need a decision rather than a formula.
   ========================================================================== */

/* --- Page shell --------------------------------------------------------- */

/* The page itself is full-bleed, so the header and footer span the viewport. */
.ch-site {
    background: var(--color-surface-base);
    color: var(--color-text-primary);
    text-align: left;
}

/* For the nav's in-page link. Scoped to the public pages so the rest of the app keeps instant jumps, and
   off for anyone who has asked for less motion - a long unrequested scroll is a vestibular trigger. */
@media (prefers-reduced-motion: no-preference) {
    html:has(.ch-site) {
        scroll-behavior: smooth;
    }
}

/* The reading column for form pages - registration, password reset - inside <main>. */
.ch-site-content {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--space-lg) var(--space-md) var(--space-2xl);
}

/* Invisible until focused, unmissable once it is. */
.ch-site-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: var(--space-xs) var(--space-sm);
    background: var(--color-surface-brand);
    color: var(--color-text-on-brand);
    border-bottom-right-radius: var(--radius-sm);
}

.ch-site-skip-link:focus {
    left: 0;
}

.ch-site-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: var(--color-surface-inverse);
}

/* Cambridge text logo then HOTmaths logo, matching the homepage header (components/Layout.module.css). */
.ch-site-header-logo {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* White as supplied, which is the Cambridge version for this dark header. Cambridge's minimum is 150px wide. */
.ch-site-logo-cambridge {
    display: block;
    width: 150px;
    height: auto;
}

/* The flame reaches below the lettering, so the nudge lines "HOTmaths" up with "CAMBRIDGE". */
.ch-site-logo-hotmaths {
    display: block;
    height: 30px;
    width: auto;
    transform: translateY(-3px);
}

.ch-site-header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

/*
 * The class is doubled to outrank vector's list reset, which is `ul:not([class*="ant-"] ul)` at (0,1,2)
 * and beats a plain `.ch-site-nav ul` at (0,1,1). Undoubled, three of its declarations came through and
 * the nav rendered with disc bullets, a 24px indent and a 4px gap under each item. Same trick, and the
 * same reason, as the `:root:root` brand ramp above.
 */
.ch-site-nav.ch-site-nav ul {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ch-site-nav.ch-site-nav li {
    margin: 0;
}

/*
 * These are links and are styled as links. An earlier pass gave them a filled pill and a rounded bar
 * across the bottom of it, which read as a row of buttons - a fair reading, since the two actual buttons
 * sit immediately to their right, and the nav then offered five button-shaped things of which only two
 * did anything button-like.
 *
 * The padding stays: with nothing painted behind it, it is invisible, and it takes each target past the
 * 24x24 minimum in WCAG 2.5.8 without changing the header's height.
 */
.ch-site-nav a {
    display: block;
    padding: var(--space-xs) var(--space-sm);
    color: var(--color-neutral-50);
    text-decoration: none;
    text-decoration-thickness: 2px;
    text-underline-offset: 6px;
}

.ch-site-nav a:hover {
    text-decoration: underline;
}

/* The bright tint is the step that reads on the dark bar; primary-600 is a text colour for light
   backgrounds and would disappear here. The radius shapes the ring only - nothing else is painted. */
.ch-site-nav a:focus-visible {
    outline: 2px solid var(--color-primary-400);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* An underline the width of the word, not a bar the width of the padded box - the latter looked like the
   bottom edge of a button. Colour is not the only signal: the label is also the heavier weight. */
.ch-site-nav a[aria-current="page"] {
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: var(--color-primary-400);
}

.ch-site-footer {
    padding: var(--space-xl) var(--space-md);
    background: var(--color-surface-inverse);
    color: var(--color-neutral-100);
}

.ch-site-footer-inner,
.ch-site-section-inner {
    max-width: 1200px;
    margin: 0 auto;
}

/* --- Sections and headings ---------------------------------------------- */

.ch-site-section {
    padding: var(--space-2xl) var(--space-md);
}

.ch-site-section--alt {
    background: var(--color-surface-raised);
}


.ch-site-section:not(.ch-site-section--alt) + .ch-site-section:not(.ch-site-section--alt),
.ch-site-section--alt + .ch-site-section--alt {
    padding-top: 0;
}


.ch-site-section-inner > :last-child,
.ch-site-measure > :last-child {
    margin-bottom: 0;
}

/* A comfortable reading width; longer lines are hard to track from end to start. */
.ch-site-measure {
    max-width: 68ch;
}

.ch-site-heading {
    margin-bottom: var(--space-md);
}

/* clamp() rather than a breakpoint: these scale with the viewport on their own. */
.ch-site-title {
    margin: 0 0 var(--space-xs);
    font-size: clamp(25px, 4vw, 34px);
    line-height: 1.2;
    font-weight: 600;
}

.ch-site-lead {
    margin: 0;
    max-width: 52ch;
    font-size: clamp(16px, 2vw, 20px);
    line-height: 1.5;
    color: var(--color-text-secondary);
}

/* --- Shared text and controls ------------------------------------------- */

.ch-site-hint {
    margin: var(--space-xs) 0 0;
    font-size: 13px;
    line-height: 20px;
    color: var(--color-text-tertiary);
}

.ch-site-hint--icon {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2xs);
}

.ch-site-field-label {
    display: block;
    margin: var(--space-sm) 0 var(--space-2xs);
    font-weight: 600;
}

.ch-site-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

/* Pins an action to the bottom of a card so buttons line up across a row. */
.ch-site-actions--bottom {
    margin-top: auto;
    padding-top: var(--space-sm);
}

/* An input and its button side by side, stacking when there is no room. */
.ch-site-input-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

.ch-site-input-row > *:first-child {
    flex: 1 1 260px;
}

.ch-site-alert {
    margin-bottom: var(--space-sm);
}

/*
 * A vector Button that has to sit inside a sentence - "I accept the Terms & Conditions". A button is the
 * right element because it opens a dialog, but vector's Button brings button geometry with it, which
 * pushed the label onto its own line.
 */
.ch-site-inline-link.ant-btn {
    display: inline;
    height: auto;
    padding: 0;
    border: 0;
    font-size: inherit;
    line-height: inherit;
    vertical-align: baseline;
}

/*
 * Vector's reset underlines every anchor, which is right for links and wrong for buttons rendered as
 * anchors. .ant-modal is listed because dialogs render through a portal outside .ch-site.
 */
.ch-site a.ant-btn,
.ant-modal a.ant-btn {
    text-decoration: none;
}

/*
 * Vector's Button capitalises its label, which suits short app labels (Save, Cancel) but mangles
 * sentence-style copy: "Get a 14-day trial" became "Get A 14-Day Trial".
 */
.ch-site .ant-btn,
.ant-modal .ant-btn {
    text-transform: none;
}

/*
 * The public template centres content, and that reaches into Ant Design's own wrappers. Stated on the
 * elements themselves so it holds whether or not that stylesheet is present.
 */
.ch-site .ant-form-item-control-input-content,
.ch-site .ant-form-item-label,
.ch-site .ant-form-item-explain,
.ch-site .ant-form-item-extra,
.ch-site .ch-site-section,
.ch-site .ch-site-step,
.ch-site .ch-site-summary {
    text-align: left;
}

/* Align the box with the first line of a wrapping label, not the middle of the block. */
.ch-site .ant-checkbox-wrapper {
    align-items: flex-start;
}

/* AntD's password field is an input inside a bordered wrapper; the template borders inputs too. */
.ch-site .ant-input-affix-wrapper > input.ant-input {
    border: none;
    box-shadow: none;
}

/* --- Grid --------------------------------------------------------------- */

/*
 * One responsive grid, used by the feature list and the lesson cards. auto-fit with minmax means the
 * column count follows the available width with no breakpoints of its own; min() stops the track
 * overflowing a narrow viewport.
 */
/* Doubled for the same reason as the nav list above - vector's `ul:not([class*="ant-"] ul)` reset
   outranks a single class, and was indenting the whole grid 24px clear of its own heading. */
.ch-site-grid.ch-site-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
    gap: var(--space-md);
    margin: var(--space-lg) 0 0;
    padding: 0;
    list-style: none;
}

.ch-site-grid.ch-site-grid > li {
    margin: 0;
}

/*
 * Fixed column counts for sets whose size is known, so the rows always come out even - auto-fit left
 * the sixth feature on a row of its own at desktop width. Each steps down at the breakpoints below
 * through a count that still divides its items (3 -> 2 -> 1, 2 -> 1).
 */
.ch-site-grid.ch-site-grid--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ch-site-grid.ch-site-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 820px) {
    .ch-site-grid.ch-site-grid--3 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 640px) {
    .ch-site-grid.ch-site-grid--2,
    .ch-site-grid.ch-site-grid--3 {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Two panels sharing a row - the homepage's trial and pricing. Stacks with the other layouts at 820px. */
.ch-site-split {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2xl);
    align-items: start;
}

@media (max-width: 820px) {
    .ch-site-split {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-xl);
    }
}

/* --- Cards and numbered steps ------------------------------------------- */

.ch-site-step {
    background: var(--color-surface-raised);
    border: 1px solid var(--color-neutral-200);
    border-radius: var(--radius-md);
    padding: var(--space-md);
}

/* The homepage's card treatment: warm neutral surface, no brand tint - orange is kept for actions and
   the few accents that carry meaning, as it is there. A completed step is shown by its number badge. */
.ch-site-step {
    margin-bottom: var(--space-md);
    border-color: var(--color-surface-raised);
}

.ch-site-step-head {
    display: flex;
    align-items: flex-start;
    gap: var(--space-xs);
    margin-bottom: var(--space-md);
}

/* Brand text on the base surface, lifted off the raised card - the homepage's icon colour. */
.ch-site-step-number {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--color-surface-base);
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    color: var(--color-text-brand);
}

.ch-site-step-number--done {
    background: var(--color-surface-brand);
    border-color: var(--color-surface-brand);
    color: var(--color-text-on-brand);
}

.ch-site-step-heading {
    flex: 1 1 auto;
    min-width: 0;
}

.ch-site-step-title {
    margin: 0;
    font-size: 18px;
    line-height: 28px;
    font-weight: 600;
}

.ch-site-step-description {
    margin: var(--space-2xs) 0 0;
    color: var(--color-text-secondary);
}

/* --- Lists -------------------------------------------------------------- */

.ch-site-rules {
    margin: var(--space-2xs) 0 0;
    padding-left: 18px;
    color: var(--color-text-secondary);
}

.ch-site-checklist {
    list-style: none;
    margin: calc(var(--space-sm) * -1) 0 var(--space-md);
    padding: 0;
    font-size: 13px;
    line-height: 22px;
    color: var(--color-text-tertiary);
}

.ch-site-checklist li {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
}

.ch-site-checklist-passed {
    color: var(--color-feedback-success-text);
}

/* --- Scrollable panel (Terms dialog) ------------------------------------ */

.ch-site-scroll {
    max-height: min(62vh, 620px);
    overflow-y: auto;
    padding-right: var(--space-sm);
    overscroll-behavior: contain;
}

.ch-site-scroll h3 {
    margin-top: var(--space-md);
}

.ch-site-scroll h4 {
    margin-top: var(--space-sm);
}

/* --- Homepage: intro ---------------------------------------------------- */

.ch-site-intro {
    padding: var(--space-2xl) var(--space-md);
    background: linear-gradient(180deg, var(--color-primary-50), var(--color-surface-base));
}

/* Two columns when there is room for both, one below that - no breakpoint needed. */
.ch-site-intro-inner {
    max-width: 1200px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    align-items: center;
    gap: var(--space-xl);
}

.ch-site-intro-text h1 {
    margin: 0 0 var(--space-sm);
    font-size: clamp(28px, 5vw, 44px);
    line-height: 1.15;
}

.ch-site-intro-image {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius-lg);
}

/* --- Homepage: features, video, pricing --------------------------------- */

.ch-site-feature {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-sm);
    background: var(--color-surface-base);
    border-radius: var(--radius-md);
}

.ch-site-feature-icon {
    flex: 0 0 auto;
    color: var(--color-text-brand);
}

.ch-site-video video {
    display: block;
    width: 100%;
    height: auto;
    /* Capped so the video does not take over a wide viewport. */
    max-height: 480px;
    border-radius: var(--radius-lg);
    background: var(--color-neutral-900);
}

.ch-site-pricing-toggle {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-bottom: var(--space-md);
}

/* Reserves the taller of the two panels so switching does not jump the page. */
.ch-site-pricing-figure {
    min-height: 96px;
}

.ch-site-price {
    margin: 0;
    font-size: clamp(32px, 6vw, 48px);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.1;
    color: var(--color-text-brand);
}

/* --- Homepage: lesson cards --------------------------------------------- */

.ch-site-lesson {
    height: 100%;
}

.ch-site-lesson-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-xs);
    height: 100%;
}

.ch-site-lesson-level {
    color: var(--color-text-tertiary);
}

.ch-site-lesson-title {
    margin: 0;
}

/* --- Registration: payment method, summary, activation code -------------- */

/*
 * Two cards rather than a dropdown: this is the choice that changes the rest of the form, so each option
 * can say what it means - which a select option cannot.
 */
.ch-site-methods {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: var(--space-xs);
    width: 100%;
}

.ch-site-methods .ant-radio-button-wrapper {
    height: auto;
    padding: var(--space-sm);
    border-radius: var(--radius-sm);
    background: var(--color-surface-base);
    /* neutral-550 rather than a paler step: a control's edge needs 3:1 against the card (WCAG 1.4.11). */
    border: 1px solid var(--color-neutral-550);
    text-align: left;
    white-space: normal;
}

/* Selected reads as chosen rather than merely outlined: a 2px brand edge, drawn as an inset shadow so
   the card does not shift. Colour is not the only signal - the radio state carries it too. */
.ch-site-methods .ant-radio-button-wrapper-checked {
    border-color: var(--color-primary-600);
    box-shadow: inset 0 0 0 1px var(--color-primary-600);
    /* AntD tints the chosen option's text; the detail line's opacity would take that under 4.5:1. The
       edge already says "chosen", so the text stays the ordinary colour. */
    color: var(--color-text-primary);
}

/* The grid positions these, so the shared-edge strip a button group draws is wrong here. */
.ch-site-methods .ant-radio-button-wrapper::before {
    display: none;
}

.ch-site-method-name {
    display: block;
    font-weight: 600;
}

.ch-site-method-detail {
    display: block;
    margin-top: 2px;
    font-size: 13px;
    line-height: 18px;
    opacity: 0.75;
}

/* The panel that takes the money - the one step-free card, set apart by its brand-coloured total. */
.ch-site-summary {
    background: var(--color-surface-raised);
    border: 1px solid var(--color-surface-raised);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
}

.ch-site-summary-title {
    margin: 0 0 var(--space-sm);
    font-size: 16px;
    font-weight: 600;
}

.ch-site-summary-line,
.ch-site-summary-total {
    display: flex;
    justify-content: space-between;
    gap: var(--space-sm);
}

.ch-site-summary-line {
    padding-bottom: var(--space-xs);
    color: var(--color-text-secondary);
}

.ch-site-summary-total {
    padding-top: var(--space-xs);
    border-top: 1px solid var(--color-neutral-200);
    font-size: 20px;
    font-weight: 600;
    color: var(--color-text-brand);
}

/*
 * Monospaced and spaced out: this is transcribed from print or pasted from an email, and every character
 * has to be checkable against the source.
 */
.ch-site-code input,
input.ch-site-code {
    font-family: 'Roboto Mono', 'Courier New', monospace;
    font-size: 17px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}


/* Wrappers that only need vertical rhythm - the rest comes from the primitives above. */
.ch-site-step-body,
.ch-site-pricing,
.ch-site-trial-form {
    margin-top: var(--space-md);
}

.ch-site-trial {
    max-width: 52ch;
}

/* --- Narrow screens ----------------------------------------------------- */

@media (max-width: 820px) {
    .ch-site-nav {
        order: 3;
        width: 100%;
    }
}

@media (max-width: 640px) {
    .ch-site-content {
        padding: var(--space-md) var(--space-sm) var(--space-xl);
    }

    .ch-site-section,
    .ch-site-intro {
        padding: var(--space-xl) var(--space-sm);
    }


    .ch-site-header {
        padding: var(--space-sm);
        gap: var(--space-xs);
    }

    .ch-site-logo-hotmaths {
        height: 26px;
    }

    .ch-site-nav.ch-site-nav ul {
        margin-left: calc(var(--space-sm) * -1);
    }

    .ch-site-nav a {
        font-size: 1.125rem;
    }

    /* Decorative, and unreadable at this size - dropped rather than cropped to a stripe. */
    .ch-site-intro-image {
        display: none;
    }

    /* Full-width actions are easier to hit than a row of small ones. */
    .ch-site-actions .ant-btn,
    .ch-site-input-row > * {
        width: 100%;
        flex: 1 1 100%;
    }

    .ch-site-video video {
        max-height: 240px;
    }
}


/*
 * HOTmaths brand colours, expressed as vector's primary ramp.
 *
 * Vector ships a muted teal primary, chosen for Edjin. HOTmaths is a separate brand, so this re-points
 * the raw --color-primary-* scale; vector's semantic tokens are var() references to it, so every
 * component follows without vector itself being touched.
 *
 * The steps are placed by the contrast each one carries, not by eye. The site's familiar #F57C00 gives
 * white text 2.70:1, below the AA minimum of 4.5:1 - so 600 is #B35A00 (4.80:1) and 800 is #874400
 * (7.05:1 on the page background). #FF860A at step 500 is closest to the familiar orange and stays
 * available for large graphics that carry no text.
 */
:root:root,
:host:host {
    /* Tints — backgrounds, badges, selected states. Never text. */
    --color-primary-50: #FFF7F0;
    --color-primary-100: #FFEBD6;
    --color-primary-200: #FFD9B2;
    --color-primary-300: #FFC080;
    --color-primary-400: #FFA242;
    --color-primary-500: #FF860A;

    /* Text-bearing steps — each placed against a measured contrast requirement. */
    --color-primary-600: #B35A00;
    --color-primary-700: #9C4F00;
    --color-primary-800: #874400;
    --color-primary-900: #613100;
}
/*
 * The legacy styles.css paints every outlined Ant Design button in --secondary-colour, a teal (#2EA88C)
 * that gives 2.84:1 on the page background - below AA for text, and a third colour the brand does not
 * use. Re-pointing the variable (rather than restyling each legacy rule) carries its hover tint along too.
 *
 * Content: --color-primary-700, 5.70:1 on the base surface and 4.95:1 on the raised one (measured).
 * Header: the dark bar needs a light step - --color-primary-300 gives 9.95:1 on --color-surface-inverse.
 */
.ch-site {
    --secondary-colour: var(--color-primary-700);
    --secondary-colour-RGB: 156, 79, 0;

    /*
     * The same file's `.ant { --ant-color-primary: var(--primary-colour) }` sits on every Ant Design
     * element and outranks the theme, so without this the selected payment card, checkboxes and focus
     * rings came out in the legacy salmon #E16558 (3.25:1 as text), and input focus in its #1890FF blue.
     * All three are re-pointed at the brand: --color-primary-600 is what the theme's colorPrimary is.
     */
    --primary-colour: var(--color-primary-600);
    --primary-colour-RGB: 179, 90, 0;
    --input-colour: var(--color-primary-600);
    --input-colour-RGB: 179, 90, 0;
    --link-colour: var(--color-primary-800);
}

.ch-site-header {
    --secondary-colour: var(--color-primary-300);
    --secondary-colour-RGB: 255, 192, 128;
}
