/*
 * public/css/vamos-brand.css
 * start.vamospanish.com - the VAMOS brand layer for the enrolment funnel.
 *
 * WHY THIS FILE EXISTS
 * The funnel was built as a separate application and never received the brand work, so it
 * shipped its own sand and terracotta palette and its own typefaces (Fraunces plus Hanken
 * Grotesk) while the rest of the estate moved to the VAMOS design system. Nothing here is
 * invented: every token below is copied value for value from the design system that already
 * ships in C:/Users/Romina/vamos-web (resources/css/tokens.css, base.css, components.css,
 * shell.css), which is the build that replaces vamospanish.com. The funnel is being made a
 * member of that family, not redesigned.
 *
 * SOURCE OF EVERY VALUE
 *   colour, radius, shadow, motion, type scale   vamos-web resources/css/tokens.css
 *   element level rules and the focus ring       vamos-web resources/css/base.css
 *   .btn family, .card, .eyebrow, .badge         vamos-web resources/css/components.css
 *   .brand-lockup                                vamos-web resources/css/shell.css
 *   form control shape                           vamos-web Components/Enquiry/enqCss.js
 *
 * SELF HOSTED FONTS, NOT GOOGLE FONTS, for the same reason vamos-web self hosts them: no
 * third party connection and no second round trip on the critical path. The two woff2 files
 * in public/fonts are byte identical copies of vamos-web/public/fonts (md5 verified).
 *
 * BACK COMPATIBILITY. The wizard's JavaScript writes two inline styles that name the old
 * --azul and --azul-2 custom properties. Rather than edit the JavaScript of a live enrolment
 * funnel, those two names survive at the bottom of :root as aliases onto the brand teal, so
 * the markup the script generates lands on brand colour without a single script change.
 *
 * No em-dashes and no en-dashes anywhere in this file, in rules or in comments.
 */

/* ==================================================================== fonts */

@font-face {
    font-family: "Bricolage Grotesque";
    font-style: normal;
    font-weight: 600 800;
    font-display: swap;
    src: url("/fonts/bricolage-grotesque-variable.woff2") format("woff2");
}

@font-face {
    font-family: "Hanken Grotesk";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/fonts/hanken-grotesk-variable.woff2") format("woff2");
}

/* ==================================================================== tokens */

:root {
    /* colour. FE-DNA-004: teal and orange are the only two brand action colours, on ink,
       with white and off white surfaces. */
    --teal-500: #2B9E9E;
    --teal-600: #238686;
    --teal-200: #4EC5CB;
    --teal-100: #9AD9E2;
    --teal-050: #F2FAFA;

    /* TEAL AS TEXT. #297F88 is the chrome layer link teal, and on a PURE WHITE surface it
       measures 4.68:1, which is where the "passes AA" claim came from. The funnel never
       paints a pure white surface behind body text: gate.blade.php and enroll.blade.php both
       lay a fixed two wash layer (body::before, z-index 0) UNDER the content (.wrap,
       z-index 1), so the real background is white with a teal or an orange wash composited
       onto it. Measured against that real background, #297F88 falls to 4.07:1 on the gate and
       4.14:1 on the wizard and MISSES the 4.5:1 floor for normal text.
       So the ramp gains its next step, --teal-800 #1F6B73, in the same hue family
       (hue 186 against the 189 of teal-700), and every teal that carries TEXT resolves there:
         #1F6B73 on the gate wash   5.35:1
         #1F6B73 on the wizard wash 5.45:1
         #1F6B73 on --teal-050      5.82:1
         #1F6B73 on pure white      6.16:1
       teal-500 and teal-600 keep their jobs as fills, borders and the focus ring. */
    --teal-700: #297F88;
    --teal-800: #1F6B73;
    --teal-text: var(--teal-800);
    --link: var(--teal-800);
    /* A link hover has to clear 4.5:1 too. teal-600 on the wash is 3.78:1 and fails, and any
       teal dark enough to pass is indistinguishable from --link, so the hover goes to ink
       (14.08:1 on the wash) and the teal underline carries the brand. This is the same move
       that .btn-ghost:hover already makes below. */
    --link-hover: var(--ink);

    --orange-500: #F07832;
    --orange-600: #D4602A;
    --orange-700: #A8481A;
    --amber: #FFC24A;
    --whatsapp: #25D366;

    --ink: #0D2424;
    --dark: #0D2424;
    --muted: #59706E;
    --line: #E4EDEC;

    --bg: #FFFFFF;
    --bg-soft: #F4FAF9;
    --cream: #FAF8F3;

    /* --line is a 1.19:1 hairline. That is fine for decorative framing (cards, pills, the
       chip track), which WCAG 1.4.11 exempts, but an empty text field has no label inside it
       and no fill of its own, so its border IS the control and has to clear 3:1. This is an
       alias onto --muted, not a new colour: #59706E measures 5.29:1 on white and 4.60:1 on
       the darkest wash. */
    --line-strong: var(--muted);

    --success-bg: #E8F7EE;
    --success-ink: #1E7B4A;
    --warn-bg: #FFF4E0;
    --warn-ink: #8A5A00;
    --danger-bg: #FBEAEA;
    --danger-ink: #B23B3B;

    --on-dark: #CFE3E1;
    --on-dark-muted: #9FC1BE;

    /* typography */
    --f-head: "Bricolage Grotesque", "Hanken Grotesk", system-ui, -apple-system, sans-serif;
    --f-body: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;

    --text-display: clamp(2.75rem, 2.2rem + 2.4vw, 3.5rem);
    --text-h2: clamp(2.25rem, 1.9rem + 1.6vw, 2.875rem);
    --text-h3: clamp(1.75rem, 1.5rem + 1.1vw, 2.25rem);
    --text-h4: clamp(1.375rem, 1.2rem + 0.7vw, 1.625rem);
    --text-lead: clamp(1.125rem, 1.05rem + 0.3vw, 1.25rem);
    --text-body: clamp(1.0625rem, 1rem + 0.25vw, 1.125rem);
    --text-small: 0.875rem;
    --text-eyebrow: 0.75rem;

    --h1-transform: uppercase;
    --h1-weight: 700;
    --h1-leading: 0.96;
    --h1-tracking: -0.02em;

    /* spacing */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;
    --space-9: 48px;
    --space-10: 64px;
    --space-11: 80px;
    --space-12: 96px;

    /* shape. FE-DNA-006 locks the harvested 12 / 20 / 28 scale. */
    --r-xs: 12px;
    --r-sm: 20px;
    --r: 28px;
    --r-full: 999px;

    /* soft teal tinted shadows, never plain black */
    --sh-sm: 0 2px 10px rgba(13, 36, 36, .07);
    --shadow: 0 6px 24px rgba(43, 158, 158, .14);
    --sh-lg: 0 18px 52px rgba(43, 158, 158, .20);

    /* motion */
    --dur-fast: .18s;
    --dur: .3s;
    --dur-slow: .6s;
    --ease: cubic-bezier(.16, 1, .3, 1);
    --ease-spring: cubic-bezier(.22, 1, .36, 1);
    --lift: -3px;
    --lift-lg: -6px;

    /* BACK COMPATIBILITY ALIASES. Two inline styles generated by the wizard script name these.
       They resolve onto the accessible brand teal so the generated markup is on brand without
       the script being touched. Both carry small bold TEXT, so both land on --teal-800:
       --azul is the ghost "Email my plan instead" link inside the --teal-050 answer panel
       (5.82:1) and --azul-2 is the placement test link on the washed page (5.45:1). */
    --azul: var(--teal-800);
    --azul-2: var(--teal-800);
}

/* ==================================================================== base */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    overflow-x: hidden;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--f-body);
    font-size: var(--text-body);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4 {
    font-family: var(--f-head);
    color: var(--ink);
    margin: 0 0 var(--space-4);
    line-height: 1.15;
}

h1 {
    font-weight: var(--h1-weight);
    line-height: var(--h1-leading);
    letter-spacing: var(--h1-tracking);
    text-transform: var(--h1-transform);
}

h2 {
    font-size: var(--text-h4);
    font-weight: 800;
}

h3 {
    font-size: var(--text-h4);
    font-weight: 700;
}

p {
    margin: 0 0 var(--space-4);
}

a {
    color: var(--link);
}

a:hover {
    color: var(--link-hover);
}

img {
    max-width: 100%;
    display: block;
}

button {
    font-family: inherit;
}

/* One visible focus ring on every interactive element.
   outline-offset puts the ring on whatever is BEHIND the control, so it has to clear 3:1 on
   every surface the funnel has. teal-500 measures only 2.81:1 on the washed page and fails.
   teal-600 is the one teal that clears 3:1 everywhere at once:
     on the gate wash 3.78:1, on the wizard wash 3.85:1, on white 4.35:1,
     on --teal-050 4.11:1, on the dark total bar 3.73:1.
   teal-800 would be darker still on the light surfaces but drops to 2.63:1 on the dark bar,
   so the ring stays at teal-600. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--teal-600);
    outline-offset: 2px;
    border-radius: 4px;
}

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ==================================================================== brand lockup
   shell.css .brand-lockup, value for value. The wordmark is TYPE, not an image: Bricolage
   Grotesque 800 in brand teal with "Academy" as an orange uppercase eyebrow. The logo image
   is decorative because the text beside it says the same thing, so a screen reader is not
   made to say the brand name twice. */

.brand-lockup {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    min-height: 44px;
    min-width: 0;
    flex: none;
}

.brand-lockup:hover {
    color: inherit;
}

.brand-lockup__img {
    height: 40px;
    width: auto;
    display: block;
}

.brand-lockup__text {
    display: flex;
    flex-direction: column;
    line-height: 1;
    gap: 2px;
    min-width: 0;
}

/* 20px at weight 800 is LARGE text, so the floor is 3:1. teal-500 measures 3.24:1 on pure
   white but only 2.81:1 once the page wash is composited in, and fails. teal-700 is 4.07:1
   on that same wash. */
.brand-lockup__mark {
    font-family: var(--f-head);
    font-weight: 800;
    font-size: 1.25rem;
    color: var(--teal-700);
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 11px at weight 700 is NORMAL text, so the floor is 4.5:1. --orange-500 is a FILL colour:
   as text on white it is 2.82:1 and on the wash 2.45:1, both failing. --orange-700 is the
   design system orange-as-text token (it already carries .choice .price and the summary
   total) and measures 5.82:1 on white, 5.06:1 on the wash. */
.brand-lockup__sub {
    font-size: 11px;
    font-weight: 700;
    color: var(--orange-700);
    text-transform: uppercase;
    letter-spacing: .08em;
    white-space: nowrap;
}

.on-ink .brand-lockup__mark {
    color: #fff;
}

.on-ink .brand-lockup__sub {
    color: var(--amber);
}

/* ==================================================================== eyebrow and badge */

.eyebrow {
    display: inline-block;
    font-size: var(--text-eyebrow);
    text-transform: uppercase;
    letter-spacing: .08em;
    font-weight: 700;
    color: var(--teal-text);
    margin-bottom: var(--space-2);
}

/* MEASURED DEVIATION FROM vamos-web. components.css .badge-neutral puts --teal-text on a
   --teal-050 fill. With the old #297F88 that measured 4.42:1 on the fill and missed the 4.5:1
   AA floor for normal text by 0.08, so the fill was dropped here. Now that --teal-text is
   #1F6B73 the pair measures 5.82:1 and would pass either way; the white surface is kept so
   the badge matches the pills the funnel actually renders. Reported upstream rather than
   copied. */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--text-eyebrow);
    text-transform: uppercase;
    letter-spacing: .06em;
    font-weight: 700;
    padding: 6px 14px;
    border-radius: var(--r-full);
    background: var(--bg);
    border: 1px solid var(--teal-100);
    color: var(--teal-text);
}

/* ==================================================================== button
   components.css .btn family. The primary fill is --orange-500 with --ink text, measured
   5.72:1. It does NOT darken on hover: darkening a light fill under fixed dark text lowers
   the ratio to 4.25:1 and fails AA, so hover feedback is carried by the lift and the shadow. */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 44px;
    min-width: 44px;
    border-radius: var(--r-full);
    font-family: var(--f-body);
    font-weight: 700;
    font-size: var(--text-lead);
    text-decoration: none;
    border: none;
    cursor: pointer;
    padding: 12px 24px;
    transition: transform var(--dur-fast) ease, box-shadow var(--dur-fast) ease, background-color var(--dur-fast) ease;
    box-shadow: var(--sh-sm);
}

.btn:hover {
    transform: translateY(var(--lift));
    box-shadow: var(--shadow);
}

.btn:active {
    transform: scale(.97);
    box-shadow: var(--sh-sm);
}

.btn[disabled],
.btn[aria-disabled="true"] {
    background: var(--line);
    color: var(--muted);
    box-shadow: none;
    transform: none;
    cursor: not-allowed;
    animation: none;
}

.btn-primary {
    background: var(--orange-500);
    color: var(--ink);
}

.btn-primary:hover {
    background: var(--orange-500);
    color: var(--ink);
}

.btn-secondary {
    background: var(--teal-500);
    color: var(--ink);
}

.btn-secondary:hover {
    background: var(--teal-600);
    color: #fff;
}

.btn-ghost {
    background: transparent;
    color: var(--teal-text);
    border: 2px solid var(--teal-500);
    box-shadow: none;
    padding: 10px 22px;
}

/* MEASURED DEVIATION, same one as .badge above. components.css keeps --teal-text on the
   --teal-050 hover fill. The label goes to ink on hover instead, 15.31:1, and the teal border
   still carries the brand. With --teal-text now at #1F6B73 the teal on fill pair would itself
   measure 5.82:1, but ink stays because a hover that only shifts its background is a weaker
   signal than one that shifts its label too. */
.btn-ghost:hover {
    background: var(--teal-050);
    color: var(--ink);
}

.btn-lg {
    font-size: 1.0625rem;
    padding: 18px 40px;
}

.btn-sm {
    font-size: var(--text-small);
    padding: 10px 18px;
}

.btn-block {
    width: 100%;
}

/* The reference CTA pulses until hovered. Dropping it is one of the ways a port reads
   flatter than the original it came from. */
@media (prefers-reduced-motion: no-preference) {
    .btn-primary:not(:hover):not([disabled]) {
        animation: btn-pulse 3.2s ease-in-out infinite;
    }
}

@keyframes btn-pulse {
    0%,
    100% {
        box-shadow: var(--sh-sm);
    }

    50% {
        box-shadow: var(--shadow);
    }
}

/* ==================================================================== card
   components.css .card: 28px radius, hairline border that solidifies to teal on hover, a
   teal tinted shadow bloom, and the accent bar that wipes across the top edge. */

.card {
    position: relative;
    overflow: hidden;
    background: var(--bg);
    border-radius: var(--r);
    box-shadow: var(--sh-sm);
    padding: var(--space-5);
    border: 1px solid var(--line);
    transition: border-color var(--dur) ease, transform var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}

.card.hover-lift:hover,
.card.hover-lift:focus-within {
    transform: translateY(var(--lift));
    box-shadow: var(--shadow);
    border-color: var(--teal-500);
}

.card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: var(--teal-500);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform var(--dur) ease;
}

.card:hover::before,
.card:focus-within::before {
    transform: scaleX(1);
}

.card.accent-orange::before {
    background: var(--orange-500);
}

.card-soft {
    background: var(--bg-soft);
}

.card-tinted {
    background: var(--teal-050);
    border-color: var(--teal-100);
}

@media (prefers-reduced-motion: reduce) {
    .card,
    .card::before {
        transition: none;
    }

    .card.hover-lift:hover {
        transform: none;
    }
}

/* ==================================================================== form controls
   Shape and focus behaviour from Components/Enquiry/enqCss.js. The control itself keeps a
   16px font size because anything smaller makes iOS Safari zoom the page on focus. */

.f-label {
    display: block;
    font-family: var(--f-head);
    font-size: var(--text-small);
    font-weight: 700;
    color: var(--ink);
    margin-bottom: var(--space-1);
}

.f-input {
    width: 100%;
    min-height: 44px;
    padding: var(--space-2) var(--space-3);
    font-family: var(--f-body);
    font-size: 16px;
    color: var(--ink);
    background: var(--bg);
    /* 1.4.11: an empty field is identified by its border alone, so that border is not
       decorative. --line is 1.19:1 and fails; --line-strong is 5.29:1 on white. */
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    outline: none;
    transition: border-color var(--dur-fast) var(--ease);
}

/* teal-100 is 1.57:1 and teal-500 is 3.24:1 on white but only 2.81:1 once the page wash sits
   behind the field. teal-700 is 4.68:1 and teal-600 is 4.35:1, so hover and focus keep the
   3:1 floor while still reading as brand teal. */
.f-input:hover {
    border-color: var(--teal-700);
}

.f-input:focus {
    border-color: var(--teal-600);
}

.f-hint {
    margin: var(--space-1) 0 0;
    font-size: var(--text-small);
    color: var(--muted);
}
