/* ============================================================
   Prog Academy LMS — Public (pre-auth) design system
   ------------------------------------------------------------
   Landing page, login, registration, password reset and invite
   pages. Deliberately a separate layer from custom.css: it adapts
   the prog.academy marketing design system (Manrope/Inter, the
   orange→blue brand gradient, 20px cards, pill CTAs, 1200px
   content column) to an LMS product, without restyling the
   authenticated app shell.

   Themes follow the app's existing mechanism — the `data-bs-theme`
   attribute set by theme.js — so light/dark, system detection and
   persistence are unchanged. Every colour is defined for BOTH
   themes explicitly; nothing here is a mechanical inversion.
   ============================================================ */

/* ---------- Self-hosted variable fonts (no third-party RTT) ---------- */
@font-face {
    font-family: 'Inter var';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/fonts/inter-latin-wght-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                   U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                   U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Inter var';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/fonts/inter-cyrillic-wght-normal.woff2') format('woff2');
    unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
    font-family: 'Manrope var';
    font-style: normal;
    font-weight: 200 800;
    font-display: swap;
    src: url('/fonts/manrope-latin-wght-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                   U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                   U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Manrope var';
    font-style: normal;
    font-weight: 200 800;
    font-display: swap;
    src: url('/fonts/manrope-cyrillic-wght-normal.woff2') format('woff2');
    unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* ---------- Tokens ---------- */
.lms-public {
    /* Brand — the prog.academy hues.
       Two ramps on purpose: --pub-gradient is the marketing gradient and is used
       only for decoration (glows, icon tiles, the progress bar, soft fills), while
       --pub-gradient-cta carries white text. White on #ff5a14 is 3.1:1, so the
       bright ramp would fail WCAG AA on the primary button and the CTA band; the
       darkened ramp stays clearly the same brand and never drops below 4.8:1. */
    --pub-brand: #ff5a14;
    --pub-brand-strong: #c23600;   /* AA on every light surface, incl. the tinted chip fill */
    --pub-blue: #006aff;
    --pub-blue-strong: #0050cc;
    --pub-gradient: linear-gradient(106deg, #ff5a14 0%, #006aff 100%);
    --pub-gradient-cta: linear-gradient(106deg, #cc4100 0%, #0047b8 100%);
    --pub-gradient-soft: linear-gradient(106deg, rgba(255, 90, 20, .14) 0%, rgba(0, 106, 255, .14) 100%);

    /* Surfaces (light) */
    --pub-bg: #f7f8fb;
    --pub-bg-band: #eef1f7;
    --pub-surface: #ffffff;
    --pub-surface-2: #f2f4f9;
    --pub-line: #e1e4eb;
    --pub-line-strong: #cdd2dd;

    /* Text (light) */
    --pub-text: #16182a;
    --pub-text-2: #414a68;
    --pub-text-3: #616881;

    --pub-shadow-sm: 0 1px 2px rgba(17, 19, 28, .05);
    --pub-shadow: 0 1px 2px rgba(17, 19, 28, .04), 0 6px 20px rgba(17, 19, 28, .06);
    --pub-shadow-lg: 0 20px 48px rgba(17, 19, 28, .12);
    --pub-ring: 0 0 0 3px rgba(0, 106, 255, .25);

    --pub-radius-pill: 999px;
    --pub-radius-card: 20px;
    --pub-radius-tile: 12px;
    --pub-radius-input: 12px;
    --pub-max: 1200px;

    --pub-accent-on-surface: #0050cc;

    font-family: 'Inter var', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    color: var(--pub-text);
    background-color: var(--pub-bg);
}

[data-bs-theme="dark"] .lms-public {
    --pub-bg: #06070b;
    --pub-bg-band: #0b0d14;
    --pub-surface: #12141d;
    --pub-surface-2: #171a25;
    --pub-line: #232739;
    --pub-line-strong: #333850;

    --pub-text: #eef0f7;
    --pub-text-2: #b9bfd6;
    --pub-text-3: #838aa6;

    --pub-shadow-sm: 0 1px 3px rgba(0, 0, 0, .5);
    --pub-shadow: 0 2px 10px rgba(0, 0, 0, .45);
    --pub-shadow-lg: 0 24px 60px rgba(0, 0, 0, .6);
    --pub-ring: 0 0 0 3px rgba(77, 141, 255, .35);

    /* On dark surfaces the pure brand hues sit too low against the background;
       these lifted variants clear AA against #06070b and the card colours. */
    --pub-accent-on-surface: #7fa9ff;
    --pub-brand-strong: #ff8a4d;
}

/* ---------- Shell ---------- */
.lms-public {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100svh;
    width: 100%;
    /* Nothing on a public page may cause a sideways scroll on a 320px phone. */
    overflow-x: clip;
}

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

.pub-main { flex: 1 1 auto; }

.pub-container {
    width: 100%;
    max-width: var(--pub-max);
    margin: 0 auto;
    padding-inline: 1rem;
}
@media (min-width: 576px) { .pub-container { padding-inline: 1.5rem; } }
@media (min-width: 992px) { .pub-container { padding-inline: 2rem; } }

.pub-section { padding-block: 3.5rem; position: relative; }
@media (min-width: 768px) { .pub-section { padding-block: 4.5rem; } }
@media (min-width: 1200px) { .pub-section { padding-block: 5.5rem; } }

/* Alternating band gives a long page rhythm without extra decoration. */
.pub-band { background-color: var(--pub-bg-band); }

/* Two stacked .pub-section paddings put ~11rem between the last card and the
   closing call to action on a desktop, which reads as a stray block rather than
   the end of the page. Dropping the top padding leaves exactly the previous
   section's bottom padding — the same distance the CTA keeps from the footer. */
.pub-section-tight { padding-top: 0; }

/* ---------- Typography ---------- */
.lms-public h1,
.lms-public h2,
.lms-public h3,
.lms-public h4,
.pub-display {
    font-family: 'Manrope var', Manrope, 'Inter var', system-ui, sans-serif;
    letter-spacing: -.02em;
    color: var(--pub-text);
}

.pub-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--pub-brand-strong);
    margin-bottom: .85rem;
}

.pub-h1 {
    font-size: clamp(2.1rem, 7.5vw, 3.9rem);
    font-weight: 800;
    line-height: 1.06;
    margin: 0;
}
.pub-h2 {
    font-size: clamp(1.6rem, 4.6vw, 2.6rem);
    font-weight: 800;
    line-height: 1.14;
    margin: 0;
}
.pub-h3 {
    font-size: clamp(1.1rem, 2.4vw, 1.3rem);
    font-weight: 700;
    line-height: 1.3;
    margin: 0;
}

.pub-lead {
    font-size: clamp(1rem, 2.1vw, 1.175rem);
    line-height: 1.65;
    color: var(--pub-text-2);
}
.pub-body { color: var(--pub-text-2); line-height: 1.7; }
.pub-muted { color: var(--pub-text-3); }
.pub-small { font-size: .875rem; }

/* The gradient headline is real text, not decoration, so it uses the CTA ramp in
   light mode (the bright orange end is only 2.9:1 on the page background, below the
   3:1 large-text floor). On dark, the bright ramp clears it comfortably. */
.pub-gradient-text {
    /* background-image, never the `background` shorthand: the shorthand resets
       background-clip, and a theme override written that way turns the headline
       into a solid gradient block instead of gradient-filled letters. */
    background-image: var(--pub-gradient-cta);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    /* A gradient headline must not become invisible if the clip is unsupported. */
    -webkit-text-fill-color: transparent;
}
[data-bs-theme="dark"] .pub-gradient-text { background-image: var(--pub-gradient); }
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .pub-gradient-text { color: var(--pub-brand-strong); -webkit-text-fill-color: currentColor; }
}

.pub-section-head { max-width: 44rem; margin-bottom: 2.25rem; }
.pub-section-head .pub-lead { margin-top: .85rem; }
.pub-section-head.is-centered { margin-inline: auto; text-align: center; }

/* ---------- Buttons ---------- */
.pub-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .55rem;
    min-height: 48px;
    padding: .75rem 1.6rem;
    border-radius: var(--pub-radius-pill);
    border: 1px solid transparent;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition: transform .12s ease, box-shadow .15s ease, background-color .15s ease,
                border-color .15s ease, color .15s ease, filter .15s ease;
}
.pub-btn:active { transform: translateY(1px); }
.pub-btn:focus-visible {
    outline: 2px solid var(--pub-blue);
    outline-offset: 2px;
}

.pub-btn-primary {
    background: var(--pub-gradient-cta);
    color: #fff;
    box-shadow: 0 8px 22px -10px rgba(0, 106, 255, .55);
}
.pub-btn-primary:hover { color: #fff; filter: brightness(1.06); box-shadow: 0 12px 28px -10px rgba(0, 106, 255, .6); }
[data-bs-theme="dark"] .pub-btn-primary { box-shadow: 0 8px 26px -10px rgba(255, 90, 20, .55); }

.pub-btn-secondary {
    background: var(--pub-surface);
    color: var(--pub-text);
    border-color: var(--pub-line-strong);
    box-shadow: var(--pub-shadow-sm);
}
.pub-btn-secondary:hover { background: var(--pub-surface-2); color: var(--pub-text); border-color: var(--pub-text-3); }

.pub-btn-ghost {
    background: transparent;
    color: var(--pub-text-2);
    border-color: transparent;
}
.pub-btn-ghost:hover { background: var(--pub-surface-2); color: var(--pub-text); }

.pub-btn-block { width: 100%; }
.pub-btn-lg { min-height: 54px; padding: .9rem 2rem; font-size: 1.0625rem; }

/* ---------- Chips / badges ---------- */
.pub-chip {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .4rem .8rem;
    border-radius: var(--pub-radius-pill);
    background: var(--pub-surface);
    border: 1px solid var(--pub-line);
    color: var(--pub-text-2);
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.2;
}
.pub-chip-brand {
    background: rgba(255, 90, 20, .09);
    border-color: rgba(255, 90, 20, .32);
    color: var(--pub-brand-strong);
}
[data-bs-theme="dark"] .pub-chip-brand { background: rgba(255, 90, 20, .12); }

.pub-badge-free {
    background: rgba(26, 127, 75, .1);
    border-color: rgba(26, 127, 75, .3);
    color: #14663b;
}
[data-bs-theme="dark"] .pub-badge-free { color: #63d19b; background: rgba(26, 127, 75, .16); border-color: rgba(99, 209, 155, .28); }

/* ---------- Cards ---------- */
.pub-card {
    background: var(--pub-surface);
    border: 1px solid var(--pub-line);
    border-radius: var(--pub-radius-card);
    padding: 1.5rem;
    box-shadow: var(--pub-shadow);
    height: 100%;
    display: flex;
    flex-direction: column;
}
@media (min-width: 768px) { .pub-card { padding: 1.75rem; } }

.pub-card-hover { transition: transform .15s ease, box-shadow .18s ease, border-color .18s ease; }
.pub-card-hover:hover {
    transform: translateY(-2px);
    border-color: var(--pub-line-strong);
    box-shadow: var(--pub-shadow-lg);
}
@media (prefers-reduced-motion: reduce) {
    .pub-card-hover:hover { transform: none; }
    .pub-btn:active { transform: none; }
}

.pub-card p:last-child { margin-bottom: 0; }

.pub-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex: 0 0 auto;
    border-radius: var(--pub-radius-tile);
    background: var(--pub-gradient-soft);
    color: var(--pub-accent-on-surface);
    margin-bottom: 1.1rem;
}
.pub-icon svg { width: 22px; height: 22px; }

/* ---------- Grids ---------- */
.pub-grid { display: grid; gap: 1.25rem; }
@media (min-width: 640px)  { .pub-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 640px)  { .pub-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px)  { .pub-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 640px)  { .pub-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .pub-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ---------- Feature list ---------- */
.pub-list { list-style: none; margin: 0; padding: 0; }
.pub-list li {
    position: relative;
    padding-left: 1.75rem;
    margin-bottom: .65rem;
    color: var(--pub-text-2);
    line-height: 1.6;
}
.pub-list li:last-child { margin-bottom: 0; }
.pub-list li::before {
    content: '';
    position: absolute;
    left: 0;
    top: .45em;
    width: 1.05rem;
    height: 1.05rem;
    border-radius: 50%;
    background: var(--pub-gradient-soft) no-repeat center;
}
.pub-list li::after {
    content: '';
    position: absolute;
    left: .28rem;
    top: .72em;
    width: .5rem;
    height: .26rem;
    border-left: 2px solid var(--pub-accent-on-surface);
    border-bottom: 2px solid var(--pub-accent-on-surface);
    transform: rotate(-45deg);
}

/* ---------- Public header ---------- */
.pub-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: color-mix(in srgb, var(--pub-bg) 88%, transparent);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--pub-line);
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .pub-header { background: var(--pub-bg); }
}

.pub-header-inner {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-height: 66px;
    padding-block: .6rem;
}

.pub-brand {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    text-decoration: none;
    color: var(--pub-text);
    font-weight: 700;
    flex: 0 0 auto;
}
.pub-brand img { height: 30px; width: auto; display: block; }
.pub-brand-name {
    font-family: 'Manrope var', Manrope, system-ui, sans-serif;
    font-size: 1.0625rem;
    letter-spacing: -.02em;
    white-space: nowrap;
}
@media (max-width: 420px) { .pub-brand-name { display: none; } }

.pub-nav {
    display: none;
    align-items: center;
    gap: .15rem;
    margin-left: 1.25rem;
}
@media (min-width: 992px) { .pub-nav { display: flex; } }
.pub-nav a {
    padding: .5rem .75rem;
    border-radius: 8px;
    font-size: .9375rem;
    font-weight: 500;
    color: var(--pub-text-2);
    text-decoration: none;
}
.pub-nav a:hover { color: var(--pub-text); background: var(--pub-surface-2); }
.pub-nav a:focus-visible { outline: 2px solid var(--pub-blue); outline-offset: 2px; }

.pub-header-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: .4rem;
}
.pub-header-actions .pub-btn { min-height: 40px; padding: .45rem 1.1rem; font-size: .9375rem; }
/* Below lg the "Log in" text link is redundant with the primary CTA. */
@media (max-width: 767.98px) { .pub-header-login { display: none; } }

/* Icon buttons (theme + language) share one 40px hit target. */
.pub-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    min-width: 40px;
    height: 40px;
    padding: 0 .55rem;
    border-radius: var(--pub-radius-pill);
    border: 1px solid var(--pub-line);
    background: var(--pub-surface);
    color: var(--pub-text-2);
    font-size: .8125rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.pub-icon-btn:hover { background: var(--pub-surface-2); color: var(--pub-text); border-color: var(--pub-line-strong); }
.pub-icon-btn:focus-visible { outline: 2px solid var(--pub-blue); outline-offset: 2px; }
.pub-icon-btn svg { width: 18px; height: 18px; }

/* ---------- Language switcher (anonymous: plain ?lang= links) ---------- */
.pub-lang { position: relative; }
.pub-lang-menu {
    position: absolute;
    right: 0;
    top: calc(100% + .4rem);
    min-width: 11rem;
    padding: .35rem;
    margin: 0;
    list-style: none;
    background: var(--pub-surface);
    border: 1px solid var(--pub-line);
    border-radius: var(--pub-radius-tile);
    box-shadow: var(--pub-shadow-lg);
    z-index: 1040;
}
.pub-lang-menu[hidden] { display: none; }
.pub-lang-menu a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .55rem .7rem;
    border-radius: 8px;
    color: var(--pub-text-2);
    text-decoration: none;
    font-size: .9375rem;
}
.pub-lang-menu a:hover { background: var(--pub-surface-2); color: var(--pub-text); }
.pub-lang-menu a:focus-visible { outline: 2px solid var(--pub-blue); outline-offset: -2px; }
.pub-lang-menu a[aria-current="true"] { color: var(--pub-accent-on-surface); font-weight: 600; }
.pub-lang-check { width: 1rem; height: 1rem; flex: 0 0 auto; }

/* ---------- Hero ---------- */
.pub-hero {
    position: relative;
    overflow: hidden;
    padding-block: 3rem 3.5rem;
}
@media (min-width: 768px)  { .pub-hero { padding-block: 4rem 4.5rem; } }
@media (min-width: 1200px) { .pub-hero { padding-block: 5rem 5.5rem; } }

/* Two soft brand glows — the marketing site's signature backdrop, at a much
   lower intensity so form text stays the highest-contrast thing on the page. */
.pub-hero::before {
    content: '';
    position: absolute;
    inset: -20% -10% auto -10%;
    height: 70%;
    background:
        radial-gradient(45% 60% at 18% 0%, rgba(255, 90, 20, .14) 0%, rgba(255, 90, 20, 0) 65%),
        radial-gradient(45% 60% at 82% 8%, rgba(0, 106, 255, .16) 0%, rgba(0, 106, 255, 0) 65%);
    pointer-events: none;
}
[data-bs-theme="dark"] .pub-hero::before {
    background:
        radial-gradient(45% 60% at 18% 0%, rgba(255, 90, 20, .2) 0%, rgba(255, 90, 20, 0) 65%),
        radial-gradient(45% 60% at 82% 8%, rgba(0, 106, 255, .22) 0%, rgba(0, 106, 255, 0) 65%);
}

.pub-hero-grid {
    position: relative;
    display: grid;
    gap: 2.5rem;
    align-items: center;
}
@media (min-width: 992px) {
    .pub-hero-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 3rem; }
}

.pub-hero-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.75rem; }
.pub-hero-actions .pub-btn { flex: 1 1 14rem; }
@media (min-width: 480px) { .pub-hero-actions .pub-btn { flex: 0 0 auto; } }

.pub-hero-bullets { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.5rem; }

/* Four benefits. The descriptions are the part people actually read, so they get
   a reading size and leading rather than caption treatment — and the column
   count then steps up only where a column is still wide enough to hold two or
   three full lines of that text. */
.pub-stats {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
    margin-top: 2.25rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--pub-line);
}
/* Measured: two-up on a 320px screen leaves ~17 characters a line, which wraps
   the descriptions into four and five ragged two-word lines; four-up below
   1000px is the same problem one step later. */
@media (min-width: 480px)  { .pub-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; } }
@media (min-width: 720px)  { .pub-stats { gap: 1.75rem 2rem; } }
@media (min-width: 1000px) { .pub-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.pub-stat-value {
    font-family: 'Manrope var', Manrope, system-ui, sans-serif;
    font-size: clamp(1.4rem, 3.5vw, 1.75rem);
    font-weight: 800;
    /* The font's own line box. At 1.15 the descender of a word like "Одразу"
       hung below it and left only ~4px of air above the description, so the
       margin below was being spent on the glyph instead of on the gap. */
    line-height: 1.35;
    color: var(--pub-text);
}
.pub-stat-label {
    /* --pub-text-2, not the muted --pub-text-3: still clearly secondary to the
       value above it, but readable rather than greyed out. */
    margin-top: .55rem;
    font-size: .875rem;
    line-height: 1.55;
    color: var(--pub-text-2);
    /* Evens the two or three lines out instead of leaving a single orphan word
       on the last one. Ignored where unsupported — nothing depends on it. */
    text-wrap: balance;
    overflow-wrap: break-word;
}
@media (min-width: 1000px) { .pub-stat-label { font-size: .9375rem; } }

/* ---------- Product visual: a small, honest mock of the coding workspace ---------- */
.pub-visual {
    border-radius: var(--pub-radius-card);
    border: 1px solid var(--pub-line);
    background: var(--pub-surface);
    box-shadow: var(--pub-shadow-lg);
    overflow: hidden;
}
.pub-visual-bar {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .7rem .9rem;
    border-bottom: 1px solid var(--pub-line);
    background: var(--pub-surface-2);
}
.pub-visual-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--pub-line-strong); }
.pub-visual-title {
    margin-left: .5rem;
    font-size: .78rem;
    font-weight: 600;
    color: var(--pub-text-3);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.pub-code {
    margin: 0;
    padding: 1rem 1.1rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .8125rem;
    line-height: 1.75;
    color: var(--pub-text-2);
    overflow-x: auto;
    white-space: pre;
    tab-size: 2;
}
@media (min-width: 400px) { .pub-code { font-size: .875rem; } }
.pub-code .k { color: #b3309a; font-weight: 600; }
.pub-code .s { color: #1a7f4b; }
.pub-code .c { color: var(--pub-text-3); font-style: italic; }
[data-bs-theme="dark"] .pub-code .k { color: #ff9ce6; }
[data-bs-theme="dark"] .pub-code .s { color: #7ee2a8; }

.pub-visual-result {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .85rem 1.1rem;
    border-top: 1px solid var(--pub-line);
    background: rgba(26, 127, 75, .07);
    color: #14663b;
    font-size: .875rem;
    font-weight: 600;
}
[data-bs-theme="dark"] .pub-visual-result { background: rgba(26, 127, 75, .14); color: #74dda6; }
.pub-visual-result svg { width: 18px; height: 18px; flex: 0 0 auto; }

/* Progress rail used in the "learning progress" card. */
.pub-progress {
    height: 8px;
    border-radius: var(--pub-radius-pill);
    background: var(--pub-surface-2);
    border: 1px solid var(--pub-line);
    overflow: hidden;
}
.pub-progress > span { display: block; height: 100%; background: var(--pub-gradient); }

/* ---------- Split feature rows (career tools) ---------- */
.pub-split { display: grid; gap: 2rem; align-items: center; }
@media (min-width: 992px) {
    .pub-split { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3.5rem; }
    .pub-split.is-reversed > *:first-child { order: 2; }
}

/* ---------- CTA band ---------- */
.pub-cta {
    border-radius: var(--pub-radius-card);
    padding: 2.25rem 1.5rem;
    text-align: center;
    background: var(--pub-gradient-cta);
    color: #fff;
    box-shadow: var(--pub-shadow-lg);
}
@media (min-width: 768px) { .pub-cta { padding: 3rem 2.5rem; } }
.pub-cta h2, .pub-cta p { color: #fff; }
.pub-cta p { opacity: .93; }
.pub-cta .pub-btn-primary {
    background: #fff;
    color: #14224a;
    box-shadow: 0 10px 26px -12px rgba(0, 0, 0, .5);
}
.pub-cta .pub-btn-primary:hover { color: #14224a; background: #f2f5ff; }
.pub-cta .pub-btn-secondary {
    background: transparent;
    color: #fff;
    border-color: rgba(255, 255, 255, .55);
    box-shadow: none;
}
.pub-cta .pub-btn-secondary:hover { background: rgba(255, 255, 255, .14); color: #fff; border-color: #fff; }
.pub-cta .pub-btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* ---------- Footer ---------- */
.pub-footer {
    border-top: 1px solid var(--pub-line);
    background: var(--pub-surface);
    padding-block: 2.5rem;
}
.pub-footer-grid {
    display: grid;
    gap: 2rem;
    margin-bottom: 2rem;
}
@media (min-width: 768px) { .pub-footer-grid { grid-template-columns: 1.4fr 1fr 1fr; gap: 2.5rem; } }
.pub-footer h2 {
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--pub-text-3);
    margin: 0 0 .85rem;
}
.pub-footer ul { list-style: none; margin: 0; padding: 0; }
.pub-footer li { margin-bottom: .5rem; }
.pub-footer a { color: var(--pub-text-2); text-decoration: none; font-size: .9375rem; }
.pub-footer a:hover { color: var(--pub-accent-on-surface); text-decoration: underline; }
.pub-footer a:focus-visible { outline: 2px solid var(--pub-blue); outline-offset: 2px; border-radius: 3px; }
.pub-footer-bottom {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.25rem;
    align-items: center;
    justify-content: space-between;
    padding-top: 1.5rem;
    border-top: 1px solid var(--pub-line);
    color: var(--pub-text-3);
    font-size: .875rem;
}

/* ---------- Auth (login / register / reset) ---------- */
.pub-auth { padding-block: 2.5rem 3.5rem; }
@media (min-width: 992px) { .pub-auth { padding-block: 3.5rem 4.5rem; } }

.pub-auth-grid { display: grid; gap: 2.5rem; align-items: start; }
@media (min-width: 992px) {
    .pub-auth-grid { grid-template-columns: minmax(0, 27rem) minmax(0, 1fr); gap: 4rem; }
}

.pub-auth-card {
    background: var(--pub-surface);
    border: 1px solid var(--pub-line);
    border-radius: var(--pub-radius-card);
    box-shadow: var(--pub-shadow-lg);
    padding: 1.75rem 1.35rem;
}
@media (min-width: 480px) { .pub-auth-card { padding: 2rem 1.85rem; } }

.pub-auth-card-wide { max-width: 40rem; margin-inline: auto; }

.pub-auth-title { font-size: 1.5rem; font-weight: 800; margin: 0 0 .35rem; }
.pub-auth-sub { color: var(--pub-text-2); font-size: .9375rem; margin: 0 0 1.5rem; }

.pub-field { margin-bottom: 1.1rem; }
.pub-field-row { display: grid; gap: 0 1rem; }
@media (min-width: 560px) { .pub-field-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.pub-label {
    display: block;
    margin-bottom: .4rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--pub-text);
}
.pub-label .pub-req { color: var(--pub-brand-strong); margin-left: .15rem; }

/* 16px minimum keeps iOS Safari from zooming the viewport on focus. */
.pub-input {
    display: block;
    width: 100%;
    min-height: 48px;
    padding: .7rem .95rem;
    font-size: 1rem;
    font-family: inherit;
    line-height: 1.4;
    color: var(--pub-text);
    background: var(--pub-surface);
    border: 1px solid var(--pub-line-strong);
    border-radius: var(--pub-radius-input);
    transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
    -webkit-appearance: none;
    appearance: none;
}
.pub-input::placeholder { color: var(--pub-text-3); opacity: .85; }
.pub-input:hover { border-color: var(--pub-text-3); }
.pub-input:focus {
    outline: none;
    border-color: var(--pub-blue);
    box-shadow: var(--pub-ring);
}
.pub-input.is-invalid,
.pub-input[aria-invalid="true"] { border-color: #c23934; }
.pub-input.is-invalid:focus,
.pub-input[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(194, 57, 52, .22); }
[data-bs-theme="dark"] .pub-input.is-invalid,
[data-bs-theme="dark"] .pub-input[aria-invalid="true"] { border-color: #f08a86; }

.pub-hint { display: block; margin-top: .4rem; font-size: .8125rem; color: var(--pub-text-3); line-height: 1.5; }
.pub-error {
    display: block;
    margin-top: .4rem;
    font-size: .8125rem;
    font-weight: 500;
    color: #a92c27;
    line-height: 1.5;
}
[data-bs-theme="dark"] .pub-error { color: #f5a29f; }

/* Password field with a reveal toggle inside the control. */
.pub-password { position: relative; }
.pub-password .pub-input { padding-right: 3rem; }
.pub-password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 48px;
    width: 3rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    color: var(--pub-text-3);
    border-radius: var(--pub-radius-input);
    cursor: pointer;
}
.pub-password-toggle:hover { color: var(--pub-text); }
.pub-password-toggle:focus-visible { outline: 2px solid var(--pub-blue); outline-offset: -2px; }
.pub-password-toggle svg { width: 20px; height: 20px; }

.pub-form-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin: -.25rem 0 1.25rem;
}

.pub-link {
    color: var(--pub-accent-on-surface);
    font-weight: 600;
    text-decoration: none;
    font-size: .9375rem;
}
.pub-link:hover { text-decoration: underline; }
.pub-link:focus-visible { outline: 2px solid var(--pub-blue); outline-offset: 2px; border-radius: 3px; }

.pub-divider {
    display: flex;
    align-items: center;
    gap: .85rem;
    margin: 1.35rem 0;
    color: var(--pub-text-3);
    font-size: .8125rem;
}
.pub-divider::before,
.pub-divider::after { content: ''; flex: 1; height: 1px; background: var(--pub-line); }

.pub-btn-google {
    background: var(--pub-surface);
    color: var(--pub-text);
    border-color: var(--pub-line-strong);
    box-shadow: var(--pub-shadow-sm);
    font-weight: 600;
}
.pub-btn-google:hover { background: var(--pub-surface-2); color: var(--pub-text); }
.pub-btn-google svg { width: 20px; height: 20px; flex: 0 0 auto; }

.pub-auth-alt { text-align: center; margin: 1.25rem 0 0; color: var(--pub-text-2); font-size: .9375rem; }

/* ---------- Alerts (public pages) ---------- */
.pub-alert {
    display: flex;
    gap: .7rem;
    padding: .85rem 1rem;
    margin-bottom: 1.1rem;
    border-radius: var(--pub-radius-tile);
    border: 1px solid var(--pub-line);
    background: var(--pub-surface-2);
    color: var(--pub-text-2);
    font-size: .9375rem;
    line-height: 1.55;
}
.pub-alert svg { width: 20px; height: 20px; flex: 0 0 auto; margin-top: .1rem; }
.pub-alert-success { background: rgba(26, 127, 75, .08); border-color: rgba(26, 127, 75, .3); color: #14663b; }
.pub-alert-danger  { background: rgba(194, 57, 52, .08); border-color: rgba(194, 57, 52, .3); color: #a92c27; }
.pub-alert-warning { background: rgba(178, 106, 0, .1); border-color: rgba(178, 106, 0, .32); color: #8a5200; }
.pub-alert-info    { background: rgba(0, 106, 255, .08); border-color: rgba(0, 106, 255, .28); color: #0050cc; }
[data-bs-theme="dark"] .pub-alert-success { color: #74dda6; background: rgba(26, 127, 75, .16); }
[data-bs-theme="dark"] .pub-alert-danger  { color: #f5a29f; background: rgba(194, 57, 52, .16); }
[data-bs-theme="dark"] .pub-alert-warning { color: #f0c073; background: rgba(178, 106, 0, .18); }
[data-bs-theme="dark"] .pub-alert-info    { color: #8fb6ff; background: rgba(0, 106, 255, .16); }

/* ---------- Side panel next to the auth card ---------- */
.pub-auth-aside { padding-top: .5rem; }
@media (max-width: 991.98px) {
    .pub-auth-aside { border-top: 1px solid var(--pub-line); padding-top: 2rem; }
}

/* ---------- Utilities ---------- */
.pub-stack > * + * { margin-top: 1rem; }
.pub-mt-0 { margin-top: 0; }
.pub-mt-1 { margin-top: .5rem; }
.pub-mt-2 { margin-top: 1rem; }
.pub-mt-3 { margin-top: 1.5rem; }
.pub-mt-4 { margin-top: 2rem; }
.pub-mb-0 { margin-bottom: 0; }
.pub-mb-2 { margin-bottom: 1rem; }
.pub-mb-3 { margin-bottom: 1.5rem; }
.pub-center { text-align: center; }
.pub-flex { display: flex; }
.pub-wrap { flex-wrap: wrap; }
.pub-gap-2 { gap: .75rem; }
.pub-items-center { align-items: center; }
.pub-justify-center { justify-content: center; }
.pub-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Skip link — first tab stop on every public page. */
.pub-skip {
    position: absolute;
    left: .75rem;
    top: -4rem;
    z-index: 1100;
    padding: .7rem 1.1rem;
    border-radius: var(--pub-radius-tile);
    background: var(--pub-surface);
    color: var(--pub-text);
    border: 1px solid var(--pub-line-strong);
    box-shadow: var(--pub-shadow-lg);
    text-decoration: none;
    font-weight: 600;
    transition: top .15s ease;
}
.pub-skip:focus { top: .75rem; }

.lms-public :target { scroll-margin-top: 5.5rem; }

/* ============================================================
   Landing page specifics
   ============================================================ */

/* The H1 is one heading in two registers — the brand at display size, then what
   it is underneath — so it still reads as a phrase to a screen reader and to a
   crawler. Sized for a brand word, not a three-letter abbreviation: the ramp has
   to hold "Prog Academy" on a 320px screen and "Навчальна платформа" under it.

   The line-height and the padding are both about the descender, not about taste.
   Manrope asks for a 1.35em line box (ascent .94em + descent .29em); at 1.02 the
   box was shorter than the glyphs, so the tail of the "g" fell outside it — and
   because the gradient is painted with background-clip: text, anything outside
   the box gets no paint at all, so the tail was cut off rather than merely
   tight. 1.12 keeps the line visually tight for a display heading, and the
   padding covers the font's full descent (which lands ~.12em below that line
   box) so the gradient reaches the bottom of the tail whatever the brand
   word is. */
.pub-h1 .pub-gradient-text {
    display: block;
    font-size: clamp(2.4rem, 8.5vw, 4.25rem);
    line-height: 1.12;
    padding-bottom: .15em;
    letter-spacing: -.035em;
}
.pub-h1-brand {
    display: block;
    margin-top: .15rem;
    font-size: clamp(1.35rem, 5vw, 2.3rem);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -.02em;
    color: var(--pub-text);
}
.pub-h1-tagline {
    /* Clears the two-line brand lockup above it; at .9rem the tagline read as a
       third heading rather than the line that explains the two above it. */
    margin: 1.15rem 0 0;
    font-size: clamp(1rem, 2.6vw, 1.25rem);
    font-weight: 600;
    color: var(--pub-text-2);
    line-height: 1.45;
}

.pub-hero-visuals { display: grid; gap: 1rem; }

.pub-progress-card { padding: 1.25rem; gap: .85rem; }
.pub-progress-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.pub-progress-value {
    font-family: 'Manrope var', Manrope, system-ui, sans-serif;
    font-size: 1.35rem;
    font-weight: 800;
    color: var(--pub-text);
}
.pub-progress-legend {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.25rem;
    font-size: .8125rem;
    color: var(--pub-text-3);
}
.pub-progress-legend strong { color: var(--pub-text); font-weight: 700; }

/* Stats are a description list: value = term, label = description. */
.pub-stats dd { margin: 0; }
.pub-stats dt { margin: 0; }

/* A card that is itself a call to action, used to close the practice grid
   instead of adding another full-width band. */
.pub-card-cta {
    background: var(--pub-gradient-soft);
    border-color: rgba(0, 106, 255, .28);
    justify-content: center;
}
.pub-card-cta .pub-btn { align-self: flex-start; }

.pub-card-compact { padding: 1.35rem; }
.pub-card-compact .pub-h3 { font-size: 1.0625rem; }

/* ---------- Static product mocks (decorative, aria-hidden) ---------- */
.pub-mock { gap: .65rem; }
.pub-mock-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .85rem .95rem;
    border: 1px solid var(--pub-line);
    border-radius: var(--pub-radius-tile);
    background: var(--pub-surface-2);
}
.pub-mock-row strong { display: block; font-size: .9375rem; color: var(--pub-text); }
.pub-mock-meta { display: block; margin-top: .15rem; font-size: .78rem; color: var(--pub-text-3); }
.pub-mock-row .pub-chip { flex: 0 0 auto; }

.pub-mock-resume { gap: .55rem; }
.pub-mock-resume-head { display: flex; align-items: center; gap: .75rem; margin-bottom: .6rem; }
.pub-mock-resume-head > div { flex: 1 1 auto; min-width: 0; }
.pub-mock-avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--pub-gradient-soft);
    border: 1px solid var(--pub-line);
}
.pub-mock-line {
    display: block;
    height: 9px;
    border-radius: var(--pub-radius-pill);
    background: var(--pub-surface-2);
    border: 1px solid var(--pub-line);
}
.pub-mock-line-strong { background: var(--pub-gradient-soft); border-color: rgba(0, 106, 255, .25); }

/* On phones the hero visual comes after the copy and the CTA — it illustrates,
   it does not sell, so it must never push the buttons below the fold. */
@media (max-width: 991.98px) {
    .pub-hero-visuals { margin-top: .5rem; }
}

/* ============================================================
   Auth page details
   ============================================================ */

.pub-btn-sm { min-height: 40px; padding: .45rem 1rem; font-size: .875rem; }
.pub-btn-sm svg { width: 16px; height: 16px; }

.pub-install-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .35rem;
}
.pub-install-head .pub-h3 { font-size: 1rem; }

/* The post-registration Telegram invitation is an alert that contains a CTA. */
.pub-telegram-invite { display: block; }
.pub-telegram-invite strong { display: block; color: inherit; }

/* form-validation.js injects Bootstrap-shaped .invalid-feedback nodes at runtime.
   Server-rendered errors use .pub-error. Style both identically so a field looks
   the same whichever side found the problem. */
.lms-public .invalid-feedback {
    display: none;
    margin-top: .4rem;
    font-size: .8125rem;
    font-weight: 500;
    color: #a92c27;
    line-height: 1.5;
    width: 100%;
}
[data-bs-theme="dark"] .lms-public .invalid-feedback { color: #f5a29f; }

/* .is-invalid is what form-validation.js sets; it must look like [aria-invalid]. */
.lms-public .pub-input.is-invalid { border-color: #c23934; }
[data-bs-theme="dark"] .lms-public .pub-input.is-invalid { border-color: #f08a86; }

/* Single-column auth pages (forgot / reset password, error states). */
.pub-auth-card-narrow { max-width: 27rem; margin-inline: auto; }
.pub-auth-card-narrow .pub-alert:last-of-type { margin-bottom: 1.25rem; }

/* ------------------------------------------------------------
   Compatibility: pre-auth pages that still use Bootstrap markup
   (invitation registration, Google profile completion). They are
   not part of this redesign, but they render inside the public
   shell, so give them the same page rhythm and column width
   instead of the app's centred-card layout.
   ------------------------------------------------------------ */
.lms-public .login-container { margin: 3rem auto; }
.lms-public .row.justify-content-center { padding-block: 3rem; margin-inline: auto; max-width: var(--pub-max); }
.lms-public .card { border-radius: var(--pub-radius-card); }

/* Header CTA label swap. "Зареєструватися" / "Регистрация" do not fit beside the
   logo and the two icon buttons on a 320px screen; the short label does. */
.pub-label-short { display: none; }
@media (max-width: 575.98px) {
    .pub-label-full { display: none; }
    .pub-label-short { display: inline; }
    .pub-header-actions .pub-btn { padding-inline: .9rem; font-size: .875rem; }
    .pub-header-inner { gap: .35rem; }
}

/* The skip link's target is focusable (tabindex=-1); never paint a focus ring on
   the whole page region when it receives focus programmatically. */
.pub-main:focus { outline: none; }
