/* ===========================================================================
   home-overrides.css — everything the cursos homepage changes about stock Pubzi.

   Kept in a separate file on purpose: home.css stays byte-identical to the
   vendor template, so re-downloading the template never clobbers our work and
   a diff always shows exactly what we changed.
   =========================================================================== */

/* --- 1. Accent -----------------------------------------------------------
   Pubzi ships acid lime (#CBFE1C). --theme covers 310 of the ~365 accent uses
   in home.css; the remaining ~55 are hardcoded literals, rewritten in place by
   tools/recolor-theme.sh. Change both together or the page goes two-tone. */
:root {
    --theme: #CBFE1C;
}

/* --- 2. Brand wordmark ---------------------------------------------------
   Pubzi's own logo (white-logo-3.svg) is the vendor's mark, not ours, so the
   header and footer use a type-set wordmark instead. */
.brand-wordmark {
    display: inline-flex;
    align-items: baseline;
    gap: 10px;
    text-decoration: none;
    font-family: "Days One", sans-serif;
    font-size: 26px;
    line-height: 1;
    color: var(--white);
    letter-spacing: -0.01em;
}
.brand-wordmark .brand-mark {
    color: var(--theme);
    font-size: 0.85em;
}
.brand-wordmark:hover .brand-text { color: var(--theme); }
.footer-wordmark { margin-bottom: 22px; }

/* --- 3. Progress bars ----------------------------------------------------
   Stock rule is `animation: load 3s forwards` with the end width baked into
   the keyframes, and an animation's forwards fill beats an inline width — so
   `style="width:25%"` in the markup silently does nothing. Drive the end
   width off a custom property instead. Markup sets `style="--fill:25%"`. */
.gt-progress-wrapper .gt-progress-wrap .pro-items .progress-value,
.gt-progress-wrapper .gt-progress-wrap .pro-items .progress-value.style-two,
.gt-progress-wrapper .gt-progress-wrap .pro-items .progress-value.style-three {
    animation: cursos-load 1.6s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
    background: var(--theme);
}
@keyframes cursos-load {
    from { width: 0; }
    to   { width: var(--fill, 100%); }
}
@media (prefers-reduced-motion: reduce) {
    .gt-progress-wrapper .gt-progress-wrap .pro-items .progress-value {
        animation: none;
        width: var(--fill, 100%);
    }
}

/* --- 4. Marquee ----------------------------------------------------------
   Stock marquee is a strip of 120px logo tiles. We run the stack as type
   rather than borrowing brand logos, so .text-slider has to stop being an
   image box.

   TRAP: .marquee-wrapper ALSO carries the class .text-slider, and .marquee-inner
   inside it is absolutely positioned. Overriding `.text-slider { height: auto }`
   unscoped therefore collapses the whole strip to zero height and only the
   gradient blob behind it renders. Scope every override to .marquee-item. */
.marque-section .marquee-wrapper.text-slider {
    height: 120px;
}
.marque-section .marquee-item .text-slider {
    height: auto;
    display: inline-flex;
    align-items: center;
    font-family: "Days One", sans-serif;
    font-size: clamp(24px, 2.9vw, 44px);
    line-height: 1.1;
    text-transform: uppercase;
    white-space: nowrap;
    color: rgba(255, 255, 255, 0.92);
}
.marque-section .gradient-shape { opacity: 0.55; }
.marque-section .marquee-item {
    display: flex;
    align-items: center;
}
.marque-section .marquee-item::after {
    content: "";
    display: inline-block;
    width: 10px;
    height: 10px;
    margin: 0 26px;
    border-radius: 50%;
    background: var(--theme);
    opacity: 0.75;
    flex: none;
}
.marque-section .marqee-list { align-items: center; }

/* --- 5. Hero -------------------------------------------------------------
   The stock eyebrow is a typewriter effect:
       animation: typing 3s steps(30, end) 1s infinite alternate
   with @keyframes typing ending at a hardcoded `width: 17ch` — sized for
   "I am Ava Lino". "Hola, soy Raúl Contreras" is 24 characters, so it stayed
   truncated mid-surname even after the animation finished, and `alternate`
   meant it un-typed itself forever afterwards. Retype it once and settle.
   The end width overshoots on purpose so no glyph ever clips. */
.gt-hero-6 .gt-hero-content h3.text {
    display: block;
    animation: cursos-typing 2.2s steps(24, end) 0.3s 1 both;
    font-size: clamp(20px, 1.9vw, 34px);
}
@keyframes cursos-typing {
    from { width: 0; }
    to   { width: 30ch; }
}
@media (prefers-reduced-motion: reduce) {
    .gt-hero-6 .gt-hero-content h3.text { animation: none; width: auto; }
}

/* Spanish prose in ALL CAPS is markedly harder to read than English, and the
   template uppercases every paragraph. Keep the shouting for labels only. */
.gt-hero-content p,
.gt-about-text,
.gt-streaming-content p,
.gt-news-card-item-4 .gt-news-content h4,
.gt-news-card-item-4 .gt-news-content h4 a,
.footer-single-item-5 .footer-content p,
.footer-bottom-5 p {
    text-transform: none;
}

/* The "en persona" sticker is absolutely positioned at left:20%/top:16px,
   which lands on the headline unless the first <span> is long enough to open
   a gap. Park it above the block instead of inside it. */
.webkit-text-item { padding-top: 34px; }
.webkit-text-item .post-box {
    left: 50%;
    top: -6px;
    transform: translateX(-50%) rotate(-7deg);
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
}
.gt-theme-btn.gt-btn-ghost {
    background: transparent;
    color: var(--white);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}
.gt-theme-btn.gt-btn-ghost:hover {
    background: var(--white);
    color: var(--header);
}
.gt-hero-6 .gt-hero-image img {
    width: 100%;
    height: auto;
    border-radius: 8px;
}

/* --- 6. Ghost members forms ---------------------------------------------
   Ghost stamps .loading / .success / .error on the <form> itself, so both
   messages stay hidden until it does. */
.form-msg {
    display: none;
    margin: 14px 0 0;
    font-size: 15px;
}
form.success .form-msg-success { display: block; color: var(--theme); }
form.error   .form-msg-error   { display: block; color: #ff6b6b; }
form.loading button[type="submit"] { opacity: 0.6; pointer-events: none; }

.footer-signup {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}
.footer-signup input {
    flex: 1 1 200px;
    min-width: 0;
    height: 60px;
    padding: 0 18px;
    color: var(--white);
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 0;
}
.footer-signup input::placeholder { color: rgba(255, 255, 255, 0.4); }
.footer-signup input:focus {
    outline: none;
    border-color: var(--theme);
}
.footer-signup .form-msg { flex: 1 0 100%; margin-top: 0; }

/* --- 7. Footer ----------------------------------------------------------- */
.footer-social {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    margin-top: 22px;
}
.footer-social a {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--text);
    text-decoration: none;
    text-transform: uppercase;
    font-size: 14px;
    letter-spacing: 0.4px;
}
.footer-social a:hover { color: var(--theme); }
.footer-social i { color: var(--theme); }

.footer-bottom-5 {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: space-between;
    align-items: center;
    margin-top: 56px;
    padding: 26px 0;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.footer-bottom-5 p { margin: 0; font-size: 15px; }
.footer-bottom-5 a { color: var(--text); }
.footer-bottom-5 a:hover { color: var(--theme); }

/* --- 7b. Section textures ------------------------------------------------
   Two environment plates from the pack, dropped in behind otherwise flat
   sections. The plate is a ::before at low opacity inside an isolated
   stacking context, so it never competes with the copy, and it is masked to
   fade at both edges so the section still joins the page cleanly.
   The image itself comes from the template via `style="--tex: url(...)"`,
   which keeps asset paths in Handlebars where {{asset}} can resolve them. */
.cursos-textured,
.cursos-neon {
    position: relative;
    isolation: isolate;
}
.cursos-textured::before,
.cursos-neon::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: var(--tex);
    background-size: cover;
    background-position: center;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 20%, #000 80%, transparent);
    mask-image: linear-gradient(to bottom, transparent, #000 20%, #000 80%, transparent);
}
.cursos-textured::before { opacity: 0.4; }
.cursos-neon::before     { opacity: 0.3; }

/* Curriculum icons */
.pro-head .title .pro-icon {
    width: 22px;
    height: 22px;
    margin-right: 10px;
    vertical-align: -4px;
    flex: none;
}

/* --- 7c. Font Awesome weight ---------------------------------------------
   The pack ships Font Awesome *Pro* (thin/light/regular/duotone). We only
   ship the two free faces, solid + brands, which is a 6.7 MB → 399 KB saving
   and keeps us inside FA Free's terms. One thing still asked for the regular
   face: the FAQ accordion chevron, declared as
       content: "\f078"; font-family: "Font Awesome 6 Pro";
   at the default weight 400. That 404'd and left the arrows blank. Same glyph
   exists in the solid face, so just ask for 900. */
   The stock rule is six classes deep, so match its specificity or it wins. */
.gt-faq-wrapper .gt-faq-item .gt-faq-content .accordion-item .accordion-header .accordion-button::after,
.gt-faq-wrapper .gt-faq-item .gt-faq-content .accordion-item .accordion-header .accordion-button:not(.collapsed)::after {
    font-weight: 900;
}

/* That alone did not stop the request: all.min.css declares THREE @font-face
   rules pointing at fa-regular-400 — the Pro regular face plus Font Awesome's
   v4 ("FontAwesome") and v5 ("Font Awesome 5 Pro") compatibility shims, which
   no element-level audit surfaces. Identical family + descriptors means the
   last declaration wins, and this file loads after all.min.css, so redeclaring
   them against the face we actually ship kills the 404 outright. Any glyph
   that wanted regular now renders solid, which for chevrons and arrows is
   indistinguishable. */
@font-face {
    font-family: "Font Awesome 6 Pro";
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url("../webfonts/fa-solid-900.woff2") format("woff2");
}
@font-face {
    font-family: "Font Awesome 5 Pro";
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url("../webfonts/fa-solid-900.woff2") format("woff2");
}
@font-face {
    font-family: "FontAwesome";
    font-display: block;
    src: url("../webfonts/fa-solid-900.woff2") format("woff2");
}

/* --- 7d. Studio section ---------------------------------------------------
   `.superhero-image img` is stock-sized for a tall transparent character
   cutout that bleeds past its column on purpose. Ours is a square opaque
   illustration, so unconstrained it swallowed the copy beside it. Box it. */
.about-section .superhero-image {
    position: relative;
    display: flex;
    justify-content: center;
}
.about-section .superhero-image > img {
    width: 100%;
    max-width: 440px;
    height: auto;
    border-radius: 20px;
}
.about-section .game-controller-image {
    position: absolute;
    right: 0;
    bottom: 6%;
    width: clamp(90px, 12vw, 150px);
    z-index: 2;
}
.about-section .game-controller-image img { width: 100%; height: auto; }
.about-section .radius-shape1 { position: absolute; left: 2%; top: 12%; z-index: 2; }
.about-section .radius-shape2 { position: absolute; left: 6%; bottom: 10%; z-index: 2; }
@media (max-width: 991px) {
    .about-section .radius-shape1,
    .about-section .radius-shape2 { display: none; }
}

/* --- 8. News cards -------------------------------------------------------
   Posts without a feature_image render no .gt-news-image at all, which
   collapses the card in the stock flex layout. */
.gt-news-card-item-4 { height: 100%; }
.gt-news-card-item-4 .gt-news-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* --- 9. Accessibility ---------------------------------------------------- */
.skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 999;
    padding: 12px 20px;
    background: var(--theme);
    color: var(--header);
}
.skip:focus { left: 0; }
:where(a, button, input, textarea):focus-visible {
    outline: 2px solid var(--theme);
    outline-offset: 3px;
}

/* Pubzi hides the native cursor nowhere, but it does ship a custom cursor
   layer we dropped; nothing to undo. Touch targets, though, need the
   hamburger to stay tappable. */
.sidebar__toggle { cursor: pointer; }

/* --- 10. Landing pages ---------------------------------------------------
   custom-landing.hbs runs on home-shell, so it gets Pubzi's header, footer,
   type and accent for free. What it does not get is screen.css — that only
   loads on the lean default.hbs shell — so everything the landing needs lives
   here rather than there. */

.landing-content { background: var(--bg-1, #0b0b0b); }

/* Ghost renders the page body as plain markup; give it Pubzi's voice so a
   landing written as markdown still reads as designed rather than as a blog
   post that wandered in. */
.landing-body { font-size: 18px; line-height: 1.8; }
.landing-body > *:first-child { margin-top: 0; }

.landing-body h2 {
    font-family: "Days One", sans-serif;
    font-size: clamp(26px, 3.2vw, 38px);
    line-height: 1.25;
    margin: 56px 0 18px;
}
.landing-body h3 {
    font-size: clamp(20px, 2.4vw, 24px);
    margin: 40px 0 14px;
}
.landing-body p { margin: 0 0 20px; }
.landing-body strong { color: var(--white); }

.landing-body ul, .landing-body ol { margin: 0 0 24px; padding-left: 0; list-style: none; }
.landing-body ol { counter-reset: landing-step; }

/* Bulleted lists get the accent tick Pubzi uses in its feature lists. */
.landing-body ul > li {
    position: relative;
    padding-left: 32px;
    margin-bottom: 12px;
}
.landing-body ul > li::before {
    content: "";
    position: absolute;
    left: 0; top: .55em;
    width: 14px; height: 3px;
    background: var(--theme);
}

/* Numbered lists read as steps — these pages are mostly "how it works". */
.landing-body ol > li {
    counter-increment: landing-step;
    position: relative;
    padding-left: 46px;
    margin-bottom: 16px;
}
.landing-body ol > li::before {
    content: counter(landing-step);
    position: absolute;
    left: 0; top: -2px;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border: 1px solid var(--theme);
    color: var(--theme);
    border-radius: 50%;
    font-size: 14px;
    font-family: "Days One", sans-serif;
}

.landing-body blockquote {
    margin: 32px 0;
    padding: 20px 24px;
    border-left: 3px solid var(--theme);
    background: rgba(255, 255, 255, .03);
}
.landing-body blockquote p:last-child { margin-bottom: 0; }

.landing-body img { border-radius: 10px; }
.landing-body hr { border: 0; border-top: 1px solid rgba(255,255,255,.12); margin: 48px 0; }

/* Closing CTA, so a long page never dead-ends without a way to sign up. */
.landing-tail {
    margin-top: 64px;
    padding-top: 40px;
    border-top: 1px solid rgba(255, 255, 255, .12);
    text-align: center;
}
.landing-tail-note {
    margin: 16px 0 0;
    font-size: 14px;
    opacity: .6;
}

/* --- 10b. Waitlist modal -------------------------------------------------
   Seat count is fetched from /assets/data/cohorts.json — Ghost never exposes
   members to a theme, so it cannot be rendered server-side. */

.cohorte { display: inline-block; }

/* Scarcity badge under the hero CTA. A live dot reads as "right now" in a way
   that static text does not. */
.cohorte-count {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 16px 0 0;
    padding: 7px 15px 7px 12px;
    font-size: 14px;
    font-weight: 600;
    color: var(--theme);
    letter-spacing: .01em;
    border: 1px solid color-mix(in srgb, var(--theme) 40%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--theme) 10%, transparent);
}
.cohorte-count.is-urgent {
    color: #ffd166;
    border-color: rgba(255, 209, 102, .45);
    background: rgba(255, 209, 102, .12);
}

.cohorte-pulse {
    width: 8px; height: 8px; border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 0 0 currentColor;
    animation: cohorte-pulse 2s ease-out infinite;
}
@keyframes cohorte-pulse {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 70%, transparent); }
    70%  { box-shadow: 0 0 0 9px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}

/* --- 10c. Seat map -------------------------------------------------------
   One chair per place, filled ones solid. For a classroom this is the honest
   version of scarcity: it is just the room, drawn. The counts come from the
   same JSON as everything else, so it can never overstate. */

.cohorte-seats { margin: 0 0 22px; }

.cohorte-seats-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 12px;
}

.cohorte-seat {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border-radius: 9px;
    animation: cohorte-seat-in .32s ease-out backwards;
    animation-delay: calc(var(--i) * 55ms);
}
.cohorte-seat svg { width: 20px; height: 20px; stroke-width: 1.7; }

.cohorte-seat.is-taken {
    background: var(--theme);
    border: 1px solid var(--theme);
}
.cohorte-seat.is-taken svg { stroke: #0d1005; fill: none; }

.cohorte-seat.is-free {
    background: transparent;
    border: 1px dashed color-mix(in srgb, var(--theme) 55%, transparent);
    animation: cohorte-seat-in .32s ease-out backwards,
               cohorte-seat-free 2.4s ease-in-out infinite;
    animation-delay: calc(var(--i) * 55ms), calc(var(--i) * 55ms + .4s);
}
.cohorte-seat.is-free svg { stroke: color-mix(in srgb, var(--theme) 75%, transparent); fill: none; }

@keyframes cohorte-seat-in {
    from { opacity: 0; transform: translateY(6px) scale(.9); }
    to   { opacity: 1; transform: none; }
}
@keyframes cohorte-seat-free {
    0%, 100% { opacity: .45; }
    50%      { opacity: 1; }
}

.cohorte-seats-label {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--theme);
}

/* Fill bar — carries the same number for large cohorts, where drawing every
   chair would be an unreadable wall of icons. */
.cohorte-bar {
    height: 5px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .1);
    overflow: hidden;
    margin: 0 0 18px;
}
.cohorte-bar-fill {
    height: 100%; width: 0;
    border-radius: inherit;
    background: linear-gradient(90deg, color-mix(in srgb, var(--theme) 55%, transparent), var(--theme));
    transition: width 1.1s cubic-bezier(.2, .8, .2, 1);
}

@media (prefers-reduced-motion: reduce) {
    .cohorte-seat, .cohorte-pulse { animation: none; }
    .cohorte-seat.is-free { opacity: .7; }
    .cohorte-bar-fill { transition: none; }
}
.cohorte-open:disabled { opacity: .45; cursor: not-allowed; }

.cohorte-modal { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; padding: 16px; }
.cohorte-modal[hidden] { display: none; }
.cohorte-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, .78); }

.cohorte-panel {
    position: relative; z-index: 1;
    width: 100%; max-width: 440px;
    max-height: 90vh; overflow-y: auto;
    background: #14161a;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 14px;
    padding: 34px 30px;
    text-align: left;
}

.cohorte-x {
    position: absolute; top: 10px; right: 14px;
    background: none; border: 0; color: rgba(255,255,255,.5);
    font-size: 28px; line-height: 1; cursor: pointer;
}
.cohorte-x:hover { color: var(--theme); }

.cohorte-title { font-family: "Days One", sans-serif; font-size: 22px; margin: 0 0 12px; }
.cohorte-lede { font-size: 15px; opacity: .78; margin: 0 0 22px; }
.cohorte-status {
    border-left: 3px solid var(--theme);
    background: rgba(255,255,255,.04);
    padding: 10px 14px; font-size: 14px; margin: 0 0 20px;
}

.cohorte-form { display: flex; flex-direction: column; }
.cohorte-label { font-size: 14px; font-weight: 600; margin-bottom: 6px; }
.cohorte-form input[type="text"],
.cohorte-form input[type="email"] {
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .16);
    border-radius: 8px;
    color: var(--white);
    padding: 12px 14px;
    font-size: 15px;
    margin-bottom: 6px;
}
.cohorte-form input:focus { outline: 2px solid var(--theme); outline-offset: 1px; }
.cohorte-hint { font-size: 12.5px; opacity: .55; margin-bottom: 18px; }
.cohorte-submit { margin-top: 6px; border: 0; cursor: pointer; width: 100%; }

/* Ghost's members.js stamps the form with these state classes */
.cohorte-msg { font-size: 14px; margin: 14px 0 0; display: none; }
.cohorte-form.success .cohorte-msg-success { display: block; color: var(--theme); }
.cohorte-form.error .cohorte-msg-error { display: block; color: #ff6b6b; }
.cohorte-form.loading .cohorte-submit { opacity: .6; pointer-events: none; }

.cohorte-fine {
    font-size: 12.5px; opacity: .5;
    margin: 20px 0 0; padding-top: 16px;
    border-top: 1px solid rgba(255, 255, 255, .1);
}

/* --- 10d. Seat widget ----------------------------------------------------
   Appears in the hero, the closing band and the modal. Prominent by default —
   a widget nobody sees until they click is doing no work. */

.cohorte-hero-widget { margin: 26px 0 30px; max-width: 380px; }

.cohorte-widget {
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .1);
    border-radius: 14px;
    padding: 20px 22px;
}
.cohorte-panel .cohorte-widget { margin-bottom: 22px; }

.cohorte-widget-head,
.cohorte-widget-calm {
    display: flex;
    align-items: center;
    gap: 14px;
}

/* The count is the loudest thing in the widget on purpose. */
.cohorte-widget-num {
    font-family: "Days One", sans-serif;
    font-size: 46px;
    line-height: 1;
    color: var(--theme);
}

.cohorte-widget-word { display: flex; flex-direction: column; line-height: 1.3; }
.cohorte-widget-word strong { font-size: 16px; }
.cohorte-widget-word span { font-size: 13px; opacity: .6; }

.cohorte-widget-head { margin-bottom: 16px; }

/* --- 10e. Closing signup band -------------------------------------------- */

.cohorte-band {
    background:
        radial-gradient(ellipse 70% 120% at 20% 0%,
            color-mix(in srgb, var(--theme) 9%, transparent), transparent 70%),
        rgba(255, 255, 255, .02);
    border-top: 1px solid rgba(255, 255, 255, .08);
}
.cohorte-band .cohorte-widget { padding: 26px 28px; }
.cohorte-band-lede { font-size: 16px; opacity: .75; margin: 0 0 26px; max-width: 34rem; }

/* Inline form is wider than the modal's, so it does not read as a leftover
   dialog dropped into the page. */
.cohorte-form-inline { max-width: 30rem; }
.cohorte-form-inline .cohorte-submit { width: auto; align-self: flex-start; padding-inline: 34px; }

@media (max-width: 991px) {
    .cohorte-hero-widget { max-width: none; }
    .cohorte-band .row { row-gap: 32px; }
}

/* --- 10f. Scholarship seats ----------------------------------------------
   A third seat state, between taken and free: genuinely unavailable, but for
   a reason worth advertising. Gold rather than the lime used for paid seats,
   so the difference is visible at a glance and the tooltip explains it.

   These are only ever drawn for seats actually held back — the count comes
   from `scholarships` in cohorts.json and the file is public, so it has to be
   a number Raul intends to give away. */

.cohorte-seat.is-beca {
    background: color-mix(in srgb, #ffc94d 22%, transparent);
    border: 1px solid #ffc94d;
    cursor: help;
}
.cohorte-seat.is-beca svg { stroke: #ffc94d; fill: none; }

.cohorte-seat.is-beca::after {
    content: "";
    position: absolute;
    right: -2px; bottom: -2px;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: #ffc94d;
    border: 2px solid #14161a;
}
.cohorte-seat { position: relative; }

.cohorte-seat:focus-visible {
    outline: 2px solid var(--theme);
    outline-offset: 2px;
}

/* Legend under the seat map, only rendered when a cohort holds scholarships */
.cohorte-legend {
    display: flex; flex-wrap: wrap; gap: 14px;
    margin: 10px 0 0;
    font-size: 12.5px;
    opacity: .75;
}
.cohorte-legend span { display: inline-flex; align-items: center; gap: 6px; }
.cohorte-legend i {
    width: 10px; height: 10px; border-radius: 3px; display: inline-block;
}
.cohorte-legend .k-taken { background: var(--theme); }
.cohorte-legend .k-beca  { background: #ffc94d; }
.cohorte-legend .k-free  { border: 1px dashed color-mix(in srgb, var(--theme) 55%, transparent); }

/* --- 10g. Becas page -----------------------------------------------------
   Two doors of equal weight. They are visually distinct so nobody has to read
   both to work out which one is theirs — a family looking for help and a
   business looking to sponsor are different people with different anxieties. */

.becas-doors { background: rgba(255, 255, 255, .02); }

.becas-door {
    height: 100%;
    background: rgba(255, 255, 255, .04);
    border: 1px solid rgba(255, 255, 255, .1);
    border-radius: 16px;
    padding: 34px 32px;
}
.becas-door-alt {
    border-color: color-mix(in srgb, #ffc94d 40%, transparent);
    background:
        radial-gradient(ellipse 80% 120% at 100% 0%, rgba(255, 201, 77, .10), transparent 70%),
        rgba(255, 255, 255, .04);
}

.becas-door-kicker {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--theme);
}
.becas-door-alt .becas-door-kicker { color: #ffc94d; }

.becas-door-title {
    font-family: "Days One", sans-serif;
    font-size: clamp(24px, 2.6vw, 30px);
    margin: 10px 0 14px;
}
.becas-door-text { opacity: .78; margin: 0 0 26px; }

.becas-door-alt .cohorte-submit { background: #ffc94d; color: #241a00; }
.becas-door .cohorte-form-inline { max-width: none; }
.becas-door .cohorte-submit { width: 100%; align-self: stretch; }

/* --- 11. Gato Arcade section --------------------------------------------
   partials/sections/arcade.hbs. Deliberately not built from Pubzi classes:
   the arcade has its own visual language and this section borrows it, so
   everything here is ours and nothing depends on template markup that a
   re-download could change. */

.cursos-arcade {
    background:
        radial-gradient(900px 420px at 15% 0%, #1b2a0d55, transparent 62%),
        radial-gradient(760px 380px at 88% 12%, #2a1b6b44, transparent 66%),
        var(--bg-2, #14161b);
    overflow: hidden;
}

.arcade-lead {
    max-width: 62ch;
    margin: 0 auto 42px;
    text-align: center;
}
.arcade-lead p { margin: 0; font-size: 17px; line-height: 1.7; opacity: .85; }
.arcade-lead strong { color: var(--theme); font-weight: 600; }

.arcade-shot { margin: 0; }
.arcade-shot img {
    display: block; width: 100%; height: auto;
    border-radius: 12px;
    border: 1px solid #ffffff1f;
    box-shadow: 0 30px 60px -30px #000;
}
.arcade-shot figcaption {
    margin-top: 10px;
    font-size: 13.5px;
    opacity: .62;
    text-align: center;
}

/* The cabinet shot is the one that explains the whole thing, so it gets the
   full width and a lime edge glow rather than sitting in the grid. */
.arcade-shot-main {
    max-width: 940px;
    margin: 0 auto 42px;
}
.arcade-shot-main img {
    border-color: #cbfe1c40;
    box-shadow: 0 40px 90px -36px #000, 0 0 60px -20px #cbfe1c33;
}

.arcade-grid {
    display: grid;
    gap: 22px;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
    align-items: start;
}


.arcade-cta { text-align: center; margin-top: 46px; }

@media (max-width: 575px) {
    .arcade-lead { margin-bottom: 30px; }
    .arcade-shot-main { margin-bottom: 30px; }
}

/* Pubzi uppercases body copy inside these bands. That is fine for a
   one-line kicker and hard work for three lines of prose, so this section
   opts out for anything that is actually a sentence. */
.cursos-arcade .arcade-lead p,
.cursos-arcade .arcade-shot figcaption {
    text-transform: none;
    letter-spacing: normal;
}

/* --- 12. Long-form page copy ----------------------------------------
   Pubzi uppercases paragraph text in these bands. On the homepage that is a
   one-line kicker; on /about/ and the legal pages it is several hundred words
   of prose, and ALL CAPS at that length stops being a style and starts being
   an obstacle. Headings keep the template's treatment. */
.sobre-mi-body p,
.sobre-mi-body li,
.about-content .about-text,
.legal-body p,
.legal-body li {
    text-transform: none;
    letter-spacing: normal;
}
