/* cvgenerator.io — main stylesheet */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
    /* Color — primary */
    --color-primary:         #2563eb;
    --color-primary-hover:   #1d4ed8;
    --color-primary-active:  #1e40af;
    --color-primary-subtle:  #eff6ff;

    /* Color — neutral scale */
    --gray-50:  #f9fafb;
    --gray-100: #f3f4f6;
    --gray-200: #e5e7eb;
    --gray-300: #d1d5db;
    --gray-400: #9ca3af;
    --gray-500: #6b7280;
    --gray-600: #4b5563;
    --gray-700: #374151;
    --gray-800: #1f2937;
    --gray-900: #111827;

    --color-text:   var(--gray-900);
    --color-muted:  var(--gray-500);
    --color-border: var(--gray-200);
    --color-bg:     #ffffff;
    --color-bg-alt: var(--gray-50);

    /* Color — semantic status */
    --color-success:      #16a34a;
    --color-success-bg:   #dcfce7;
    --color-success-text: #166534;
    --color-warn:         #d97706;
    --color-warn-bg:      #fef3c7;
    --color-warn-text:    #92400e;
    --color-error:        #dc2626;
    --color-error-bg:     #fee2e2;
    --color-error-text:   #991b1b;
    --color-info:         var(--color-primary);
    --color-info-bg:      #dbeafe;
    --color-info-text:    #1e40af;

    /* Type scale — 1.25 ratio, base 16px */
    --fs-xs:  0.8rem;      /* 12.8px */
    --fs-sm:  0.875rem;    /* 14px   */
    --fs-base: 1rem;       /* 16px   */
    --fs-md:  1.125rem;    /* 18px   */
    --fs-lg:  1.25rem;     /* 20px   */
    --fs-xl:  1.563rem;    /* ~25px  */
    --fs-2xl: 1.953rem;    /* ~31px  */
    --fs-3xl: 2.441rem;    /* ~39px  */
    --fs-4xl: 3.052rem;    /* ~49px  */

    /* Spacing scale — 4px unit */
    --sp-1:  0.25rem;
    --sp-2:  0.5rem;
    --sp-3:  0.75rem;
    --sp-4:  1rem;
    --sp-5:  1.25rem;
    --sp-6:  1.5rem;
    --sp-8:  2rem;
    --sp-10: 2.5rem;
    --sp-12: 3rem;
    --sp-16: 4rem;
    --sp-20: 5rem;
    --sp-24: 6rem;

    /* Radii */
    --radius-sm: 0.375rem;
    --radius-lg: 0.75rem;

    /* Shadows */
    --shadow-sm: 0 1px 2px rgba(17, 24, 39, 0.06), 0 1px 3px rgba(17, 24, 39, 0.08);
    --shadow-md: 0 4px 6px rgba(17, 24, 39, 0.07), 0 10px 20px rgba(17, 24, 39, 0.10);

    --font-sans: system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
    --content-max:        68.75rem; /* 1100px */
    --content-max-narrow: 45rem;    /* 720px */
}

body {
    font-family: var(--font-sans);
    font-size: var(--fs-base);
    color: var(--color-text);
    background: var(--color-bg);
    line-height: 1.6;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

main { flex: 1; }

a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Container */
.container { max-width: var(--content-max); margin: 0 auto; padding: 0 var(--sp-5); }
.container--narrow { max-width: var(--content-max-narrow); }

/* Section */
.section { padding: var(--sp-12) 0; }

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-5);
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    border: 1px solid transparent;
    text-decoration: none;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.28);
}
.btn--primary { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }
.btn--primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); text-decoration: none; }
.btn--outline { background: transparent; color: var(--color-primary); border-color: var(--color-primary); }
.btn--outline:hover { background: var(--color-primary); color: #fff; text-decoration: none; }
.btn--secondary { background: var(--color-bg); color: var(--gray-700); border-color: var(--gray-300); }
.btn--secondary:hover { border-color: var(--gray-400); background: var(--gray-50); text-decoration: none; }
.btn--secondary:disabled { opacity: 0.6; cursor: not-allowed; }
.btn--ghost { background: transparent; color: var(--gray-700); border-color: transparent; }
.btn--ghost:hover { background: var(--gray-100); text-decoration: none; }
.btn--sm { padding: var(--sp-2) var(--sp-3); font-size: var(--fs-xs); }
.btn--lg { padding: var(--sp-4) var(--sp-8); font-size: var(--fs-md); }

/* Cards — shared component: templates gallery, tools grid, blog list */
.card {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
}

/* Navbar */
.navbar {
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: 100;
}
@supports (animation-timeline: scroll()) {
    .navbar {
        animation: navbar-shadow linear;
        animation-timeline: scroll(root);
        animation-range: 0 120px;
    }
    @keyframes navbar-shadow {
        from { box-shadow: none; }
        to   { box-shadow: var(--shadow-sm); }
    }
}
.navbar__inner { display: flex; align-items: center; gap: var(--sp-6); max-width: var(--content-max); margin: 0 auto; padding: 0 var(--sp-5); height: 3.5rem; }
.navbar__logo { font-weight: 800; font-size: var(--fs-lg); color: var(--color-text); text-decoration: none; flex-shrink: 0; }
.navbar__links { display: flex; align-items: center; gap: var(--sp-4); list-style: none; margin-left: auto; }
.navbar__links a, .navbar__dropdown-btn { color: var(--color-text); text-decoration: none; font-size: var(--fs-sm); background: none; border: none; cursor: pointer; padding: 0; }
.navbar__links a:hover, .navbar__dropdown-btn:hover { color: var(--color-primary); }
.navbar__dropdown { position: relative; }
/* Visibility is class-driven (assets/js/site.js), not hover-driven: on touch a
   tap fires mouseenter *and* click, which used to open and instantly re-close
   the menu. Pointer devices still get hover-open via the @media rule below. */
.navbar__dropdown-menu { display: none; position: absolute; top: 100%; right: 0; background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-lg); list-style: none; min-width: 11.25rem; padding: var(--sp-2) 0; box-shadow: var(--shadow-md); }
.navbar__dropdown-menu--open { display: block; }
.navbar__dropdown-menu li a { display: block; padding: var(--sp-2) var(--sp-4); font-size: var(--fs-sm); }
@media (min-width: 769px) and (hover: hover) and (pointer: fine) {
    .navbar__dropdown:hover .navbar__dropdown-menu,
    .navbar__dropdown:focus-within .navbar__dropdown-menu { display: block; }
}
.navbar__burger { display: none; flex-direction: column; align-items: center; justify-content: center; gap: 5px; background: none; border: none; cursor: pointer; width: 2.75rem; height: 2.75rem; padding: 0; margin-left: auto; margin-right: calc(var(--sp-2) * -1); }
.navbar__burger span { display: block; width: 22px; height: 2px; background: var(--color-text); border-radius: 2px; }

/* Language switcher (EN/FR, SPEC §3). Extra specificity (two classes) so it
   wins over .navbar__links a / .footer ul a / .footer ul li resets. */
.lang-switcher { display: flex; align-items: center; gap: var(--sp-2); list-style: none; }
.lang-switcher.lang-switcher li { margin: 0; }
.lang-switcher .lang-switcher__link {
    display: inline-block;
    padding: var(--sp-1) var(--sp-2);
    border-radius: var(--radius-sm);
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--color-muted);
    text-decoration: none;
    border: 1px solid transparent;
}
.lang-switcher .lang-switcher__link:hover { color: var(--color-primary); }
.lang-switcher .lang-switcher__link--current {
    color: var(--color-text);
    background: var(--color-bg-alt);
    border-color: var(--color-border);
    cursor: default;
}
.lang-switcher .lang-switcher__link--current:hover { color: var(--color-text); }

/* Screen-reader-only text */
.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-to-content link — first focusable element site-wide (views/layouts/
   main.php). Off-screen until focused, then pinned top-left above everything
   else so keyboard/screen-reader users can jump past the navbar (and, on
   pages like /templates or /resume-builder, a long filter bar or toolbar)
   straight to <main>. */
.skip-link {
    position: absolute;
    top: -40px;
    left: var(--sp-2);
    z-index: 1000;
    background: var(--color-primary);
    color: #fff;
    padding: var(--sp-2) var(--sp-4);
    border-radius: var(--radius-sm);
    text-decoration: none;
    font-weight: 600;
    transition: top 0.15s ease;
}
.skip-link:focus {
    top: var(--sp-2);
}

/* French-suggestion banner (client-side only, SPEC §3 — never auto-redirects) */
.fr-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-4);
    background: var(--color-info-bg);
    color: var(--color-text);
    padding: var(--sp-2) var(--sp-5);
    font-size: var(--fs-sm);
    text-align: center;
}
.fr-banner__text { margin: 0; }
.fr-banner__text a { color: var(--color-primary); font-weight: 600; margin-left: var(--sp-1); }
.fr-banner__close {
    background: none;
    border: none;
    font-size: var(--fs-lg);
    line-height: 1;
    cursor: pointer;
    color: var(--color-muted);
    padding: 0 var(--sp-1);
}
.fr-banner__close:hover { color: var(--color-text); }

/* Flash messages */
.flash { padding: var(--sp-3) var(--sp-5); font-size: var(--fs-sm); }
.flash--success { background: var(--color-success-bg); color: var(--color-success-text); }
.flash--error   { background: var(--color-error-bg); color: var(--color-error-text); }
.flash--warning { background: var(--color-warn-bg); color: var(--color-warn-text); }
.flash--info    { background: var(--color-info-bg); color: var(--color-info-text); }

/* Page header */
.page-header { background: var(--color-bg-alt); border-bottom: 1px solid var(--color-border); padding: var(--sp-10) 0; }
.page-header h1 { font-size: var(--fs-2xl); }
.page-header .hero__ctas { justify-content: flex-start; margin: var(--sp-6) 0; }

/* Hero — two columns on desktop (copy beside a real product screenshot),
   stacked and centered on mobile (see the 768px block below). */
.hero { padding: var(--sp-16) 0; background: var(--color-bg-alt); }
.hero__grid { display: flex; align-items: center; gap: var(--sp-10); }
.hero__content { flex: 1 1 0; min-width: 0; }
.hero h1 { font-size: clamp(2.2rem, 1.6rem + 3vw, 3.5rem); line-height: 1.15; margin: 0 0 var(--sp-5); }
.hero__sub { font-size: var(--fs-lg); color: var(--color-muted); margin: 0 0 var(--sp-8); max-width: 34rem; }
.hero__ctas { display: flex; align-items: center; justify-content: flex-start; gap: var(--sp-4); flex-wrap: wrap; }
.hero__media { flex: 1 1 0; min-width: 0; }
.hero__screenshot {
    display: block; width: 100%; height: auto;
    border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
}

/* Resume import CTA */
.resume-import { display: inline-flex; flex-direction: column; align-items: center; gap: var(--sp-2); }
.resume-import__input { display: none; }
.resume-import__error { color: var(--color-error-text); font-size: var(--fs-sm); max-width: 20rem; text-align: center; }
.resume-import__quota { text-align: center; max-width: 20rem; }
.resume-import__quota p { font-size: var(--fs-sm); color: var(--color-muted); margin-bottom: var(--sp-2); }

/* Forms */
.form { display: flex; flex-direction: column; gap: var(--sp-5); }
.form__group { display: flex; flex-direction: column; gap: var(--sp-2); }
.form__group label { font-size: var(--fs-sm); font-weight: 600; }
.form__group input[type="text"],
.form__group input[type="email"],
.form__group input[type="password"],
.form__group input[type="search"],
.form__group input[type="tel"],
.form__group input[type="number"],
.form__group select {
    height: 2.5rem;
}
.form__group textarea { min-height: 6rem; resize: vertical; }
.form__group input[type="text"],
.form__group input[type="email"],
.form__group input[type="password"],
.form__group input[type="search"],
.form__group input[type="tel"],
.form__group input[type="number"],
.form__group textarea,
.form__group select {
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    font-family: inherit;
    color: var(--color-text);
    background: var(--color-bg);
    width: 100%;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.form__group input:hover, .form__group textarea:hover, .form__group select:hover { border-color: var(--gray-400); }
.form__group input:focus, .form__group textarea:focus, .form__group select:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
input[type="checkbox"] { accent-color: var(--color-primary); }

/* Typography helpers */
h1 { font-size: var(--fs-2xl); line-height: 1.2; }
h2 { font-size: var(--fs-xl); line-height: 1.3; margin: var(--sp-6) 0 var(--sp-2); }
h3 { font-size: var(--fs-md); line-height: 1.4; margin: var(--sp-4) 0 var(--sp-1); }
p  { margin-bottom: var(--sp-3); }
ul { padding-left: var(--sp-6); margin-bottom: var(--sp-3); }
ul li { margin-bottom: var(--sp-1); }
code { font-family: monospace; background: var(--color-bg-alt); padding: 0.1em 0.35em; border-radius: 3px; font-size: 0.875em; }

/* Landing page sections */
.section--alt { background: var(--color-bg-alt); }
.section__heading { text-align: center; margin-bottom: var(--sp-8); }
.section__more { text-align: center; margin-top: var(--sp-6); }

.home-final-cta { text-align: center; }
.home-final-cta p { margin-bottom: var(--sp-5); font-size: var(--fs-lg); }

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-8); }
.step { text-align: center; }
.step__number {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.25rem; height: 2.25rem; border-radius: 50%;
    background: var(--color-primary); color: #fff; font-weight: 700;
    margin-bottom: var(--sp-3);
}
.step h3 { margin-top: var(--sp-1); }
.step p { color: var(--color-muted); margin-bottom: 0; }

.tools-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--sp-6); }
.tool-card { padding: var(--sp-6); }
.tool-card h3 { margin-top: 0; font-size: var(--fs-md); }
.tool-card p { color: var(--color-muted); }

@media (max-width: 768px) {
    .steps { grid-template-columns: 1fr; }
}

/* Templates gallery */
.template-filter-tabs { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-6); }
.template-filter-tab {
    font-size: var(--fs-sm);
    font-weight: 600;
    padding: 0.375rem var(--sp-3);
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    color: var(--color-muted);
    cursor: pointer;
    white-space: nowrap;
}
.template-filter-tab:hover { border-color: var(--color-text); color: var(--color-text); }
.template-filter-tab.is-active { background: var(--color-text); border-color: var(--color-text); color: var(--color-bg); }

.template-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--sp-6);
}
.template-card {
    display: flex;
    flex-direction: column;
}
/* The preview box is locked to the A4 ratio the previews are rendered at
   (794 x 1123 = the same paper width the builder canvas uses), so every card
   in a row is the same height whether or not its image has decoded yet, and a
   lazy image can never reflow the grid under the reader's thumb. The images
   themselves are pre-rendered WebP, so they scale by object-fit rather than by
   a transform — see MOBILE-AUDIT.md, "Gallery previews". */
.template-card__preview {
    display: block;
    background: var(--color-bg-alt);
    border-bottom: 1px solid var(--color-border);
    aspect-ratio: 794 / 1123;
    overflow: hidden;
}
.template-card__preview img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.template-card__body { padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-2); flex: 1; }
.template-card__header { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.template-card__name { margin: 0; font-size: var(--fs-lg); }
.template-card__name a { color: var(--color-text); }
.template-card__tagline { font-size: var(--fs-sm); color: var(--color-muted); flex: 1; margin: 0; }

.template-badge { display: inline-block; flex-shrink: 0; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; padding: 0.125rem var(--sp-2); border-radius: 999px; white-space: nowrap; }
.template-badge--ats { background: var(--color-success-bg); color: var(--color-success-text); }
.template-badge--hybrid { background: var(--color-info-bg); color: var(--color-info-text); }
.template-badge--showcase { background: var(--color-warn-bg); color: var(--color-warn-text); white-space: normal; }

.template-multipage-note { display: inline-block; margin-left: var(--sp-2); font-size: var(--fs-xs); color: var(--color-muted); }

/* Per-template landing page */
.template-show { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-10); align-items: start; }
.template-show__body .btn { margin-top: var(--sp-2); }
.template-show__preview img { display: block; width: 100%; height: auto; border: 1px solid var(--color-border); border-radius: var(--radius-lg); }
.template-show__others { margin-top: var(--sp-8); padding-top: var(--sp-6); border-top: 1px solid var(--color-border); }
.template-show__others h2 { margin-top: 0; }
.template-show__others ul { list-style: none; padding: 0; }
.template-show__others li { margin-bottom: var(--sp-2); font-size: var(--fs-sm); color: var(--color-muted); }

@media (max-width: 768px) {
    .template-show { grid-template-columns: 1fr; gap: var(--sp-6); }

    /* Source order is preview → description → CTA → other templates, which put
       "Use this template" ~1280px down the page. Pull the CTA above the
       description so it lands within the first scroll. */
    .template-show__body { display: flex; flex-direction: column; }
    .template-show__body > .btn { order: 1; margin-top: 0; align-self: stretch; }
    .template-show__body > p { order: 2; margin-top: var(--sp-5); }
    .template-show__others { order: 3; }

    /* A full-page resume render at 90vw is ~505px — 60% of the viewport before
       a word of copy. Cap it; object-fit keeps the A4 ratio. */
    .template-show__preview img { max-height: 55vh; width: auto; margin: 0 auto; object-fit: contain; }

    /* All 65 templates link to each other. Keeping every link (they are the
       internal-linking graph) but dropping the repeated taglines and going
       two-up takes this block from ~4700px to roughly a quarter of that. */
    .template-show__others ul { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-4); }
    .template-show__others li { margin-bottom: 0; }
    .template-show__others li a { display: flex; align-items: center; min-height: 2.75rem; }
    .template-show__other-tagline { display: none; }
}

/* Footer */
.footer { background: var(--color-bg-alt); border-top: 1px solid var(--color-border); padding: var(--sp-12) 0 var(--sp-6); margin-top: auto; }
.footer__inner { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--sp-8); max-width: var(--content-max); margin: 0 auto; padding: 0 var(--sp-5); }
.footer__logo { font-weight: 800; font-size: var(--fs-lg); color: var(--color-text); text-decoration: none; display: block; margin-bottom: var(--sp-2); }
.footer__tagline { font-size: var(--fs-sm); color: var(--color-muted); }
.footer__heading { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin-bottom: var(--sp-3); }
.footer ul { list-style: none; padding: 0; margin: 0; }
.footer ul li { margin-bottom: var(--sp-2); }
.footer ul a { font-size: var(--fs-sm); color: var(--color-text); }
.footer ul a:hover { color: var(--color-primary); }
.footer__bottom {
    display: flex;
    flex-wrap: wrap-reverse;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    max-width: var(--content-max);
    margin: var(--sp-8) auto 0;
    padding: var(--sp-4) var(--sp-5) 0;
    border-top: 1px solid var(--color-border);
}
.footer__bottom p { font-size: var(--fs-sm); color: var(--color-muted); margin: 0; }

/* ======================================================================
   Responsive shell
   Mobile rules for the site chrome only (navbar, footer, typography, tap
   targets, form fields). Resume templates are frozen for mPDF parity — no
   rule here may reach inside .resume-page. See MOBILE-AUDIT.md.
   ====================================================================== */
@media (max-width: 768px) {
    /* --- navigation --- */
    .navbar__burger { display: flex; }
    .navbar__links {
        display: none;
        flex-direction: column;
        align-items: stretch;
        position: absolute;
        top: 3.5rem;
        left: 0;
        right: 0;
        background: var(--color-bg);
        border-bottom: 1px solid var(--color-border);
        box-shadow: var(--shadow-sm);
        padding: var(--sp-2) var(--sp-5) var(--sp-4);
        gap: 0;
        /* A long tools list plus the auth row must scroll, not run off-screen. */
        max-height: calc(100vh - 3.5rem);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
    .navbar__links--open { display: flex; }
    .navbar__links > li { width: 100%; }
    .navbar__links > li > a,
    .navbar__dropdown-btn {
        display: flex;
        align-items: center;
        width: 100%;
        min-height: 2.75rem;
        font-size: var(--fs-base);
    }
    .navbar__dropdown-menu {
        position: static;
        display: none;
        border: none;
        box-shadow: none;
        border-radius: 0;
        min-width: 0;
        padding: 0 0 var(--sp-2) var(--sp-4);
    }
    .navbar__dropdown-menu--open { display: block; }
    .navbar__dropdown-menu li a {
        display: flex;
        align-items: center;
        min-height: 2.75rem;
        padding: 0;
        font-size: var(--fs-base);
    }
    .navbar__auth { display: flex; align-items: center; gap: var(--sp-3); min-height: 2.75rem; flex-wrap: wrap; }

    /* --- footer --- */
    .footer { padding-top: var(--sp-10); }
    .footer__inner { grid-template-columns: 1fr 1fr; gap: var(--sp-6); }
    .footer ul li { margin-bottom: 0; }
    .footer ul a { display: flex; align-items: center; min-height: 2.75rem; }
    .footer__bottom { flex-direction: column; align-items: flex-start; }

    /* --- tap targets (WCAG 2.5.8) --- */
    .navbar__logo { display: flex; align-items: center; min-height: 2.75rem; }
    .footer__logo { min-height: 2.75rem; display: flex; align-items: center; }
    .lang-switcher { gap: var(--sp-1); }
    .lang-switcher .lang-switcher__link {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 2.75rem;
        min-width: 2.75rem;
        font-size: var(--fs-sm);
    }
    /* nowrap on a long label (e.g. the tracker's "Sign in with Google" CTA)
       pushes past a 360px viewport — let mobile buttons wrap instead. */
    .btn { min-height: 2.75rem; white-space: normal; }
    .fr-banner { justify-content: space-between; text-align: left; gap: var(--sp-2); padding-right: var(--sp-2); }
    .fr-banner__close {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
        min-width: 2.75rem;
        min-height: 2.75rem;
    }
    .template-filter-tab,
    .ats-tool__tab { min-height: 2.75rem; }
    .template-card__header { flex-wrap: wrap; }

    /* Gallery: two columns across phone widths. auto-fill with a 220px min
       collapses to one column below ~500px, which wastes half the screen on a
       gallery whose whole job is comparison — so pin it to 2 and drop to 1
       only where a card would be narrower than ~150px. */
    .template-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); }
    .template-card__body { padding: var(--sp-3); gap: var(--sp-1); }
    .template-card__name { font-size: var(--fs-md); }
    .template-card__tagline { font-size: var(--fs-xs); }
    /* A ~156px card is narrower than "ATS-friendly"/"Compatible ATS" set on
       one line — the badge has to be allowed to wrap inside it. */
    .template-card .template-badge { white-space: normal; max-width: 100%; }
    .template-card:hover { transform: none; }   /* no hover lift on touch */

    /* --- form fields: <16px triggers iOS auto-zoom on focus. Checkboxes are
           excluded so nothing reaches the templates' edit-mode checkbox. --- */
    input:not([type="checkbox"]):not([type="radio"]),
    textarea,
    select,
    .form__group input:not([type="checkbox"]):not([type="radio"]),
    .form__group textarea,
    .form__group select { font-size: 1rem; }
    .form__group input[type="text"],
    .form__group input[type="email"],
    .form__group input[type="password"],
    .form__group input[type="search"],
    .form__group input[type="tel"],
    .form__group input[type="number"],
    .form__group select { height: 2.75rem; }

    /* --- typography / density --- */
    .hero { padding: var(--sp-12) 0; }
    .hero__grid { flex-direction: column; text-align: center; }
    .hero__content { text-align: center; }
    .hero__sub { margin-left: auto; margin-right: auto; }
    .hero__ctas { justify-content: center; }
    .page-header { padding: var(--sp-8) 0; }
    .section { padding: var(--sp-10) 0; }
    .hero__sub { font-size: var(--fs-md); }
    h1 { font-size: var(--fs-xl); }
    h2 { font-size: var(--fs-lg); }
    h3 { font-size: var(--fs-md); }
    .page-header h1 { font-size: var(--fs-xl); }

    /* --- containers --- */
    .container { padding: 0 var(--sp-4); }
    .navbar__inner { padding: 0 var(--sp-4); }
    .footer__inner, .footer__bottom { padding-left: var(--sp-4); padding-right: var(--sp-4); }
    .tracker-header { flex-wrap: wrap; }
    .tracker-modal { padding: var(--sp-4); }
    .profile-guide__cta { flex-direction: column; align-items: flex-start; }
}

/* ======================================================================
   Touch devices at any width — landscape phones and tablets.
   MOBILE-AUDIT.md backlog item 9.

   Every rule in the block above is keyed to `max-width: 768px`, so a phone
   rotated to landscape (844x390) matched none of them: measured at 844x390,
   inputs fell back to 14px (13.3px on the tracker's URL field) — which makes
   iOS auto-zoom the page on focus — and buttons to 34px.

   Touch-critical sizing has to key off input capability, not viewport width.
   Layout rules (column counts, density, typography, containers) correctly stay
   width-based and are deliberately NOT repeated here — a landscape phone has
   the width for the wider layout, it just doesn't have a fine pointer.

   The input selector mirrors the width-based one exactly, including the
   checkbox/radio exclusions that keep it from reaching the resume templates'
   edit-mode checkbox (templates are frozen for mPDF parity).
   ====================================================================== */
@media (hover: none) and (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]),
    textarea,
    select,
    .form__group input:not([type="checkbox"]):not([type="radio"]),
    .form__group textarea,
    .form__group select { font-size: 1rem; }

    /* min-height rather than the width-based block's fixed `height`, so a field
       that legitimately grows (a wrapped select label) isn't clipped. */
    .form__group input:not([type="checkbox"]):not([type="radio"]),
    .form__group select { min-height: 2.75rem; }

    .btn { min-height: 2.75rem; white-space: normal; }
    .lang-switcher .lang-switcher__link,
    .template-filter-tab,
    .ats-tool__tab { min-height: 2.75rem; }

    /* A landscape phone is wider than 768px, so it gets the DESKTOP navbar —
       whose Tools button measured 16px and logo 42px. Both are real tap targets
       there. 44px still fits inside the 3.5rem bar, so the bar's height is
       unchanged. */
    .navbar__logo,
    .navbar__dropdown-btn {
        display: inline-flex;
        align-items: center;
        min-height: 2.75rem;
    }
    .fr-banner__close,
    .footer__logo { min-width: 2.75rem; min-height: 2.75rem; }
    .template-card:hover { transform: none; }   /* no hover lift on touch */
}

@media (max-width: 480px) {
    .footer__inner { grid-template-columns: 1fr; }
    .hero__ctas { flex-direction: column; align-items: stretch; }
    .hero__ctas .btn, .hero__ctas .resume-import { width: 100%; }
    .ats-score__dial { width: 8rem; height: 8rem; }
    .ats-score__inner { width: 6.5rem; height: 6.5rem; font-size: var(--fs-xl); }
}

/* Wide authored content (blog tables) scrolls in its own box — site.js wraps
   every .blog-post table in this container at load. */
.table-scroll { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll table { margin-top: 0; }
.blog-post img { max-width: 100%; height: auto; }

/* Blog */
.blog-list { display: flex; flex-direction: column; gap: var(--sp-6); }
.blog-list__item { padding: var(--sp-6); }
.blog-list__meta { font-size: var(--fs-xs); color: var(--color-muted); margin-bottom: var(--sp-2); }
/* Small accent rule above each section heading: a quiet echo of the cover
   image's high-contrast graphic and the article-cta buttons' --color-primary,
   repeated at every h2 so the page doesn't read as "one bold moment up top,
   then plain text the rest of the way down". No new color, no markup change
   (the heading already renders plain from views/blog/single.php). */
.blog-post h2 { margin-top: var(--sp-8); padding-top: var(--sp-4); position: relative; }
.blog-post h2::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 2.5rem;
    height: 3px;
    background: var(--color-primary);
}
.blog-post table { width: 100%; border-collapse: collapse; margin: var(--sp-4) 0 var(--sp-6); }
.blog-post table th, .blog-post table td { border: 1px solid var(--color-border); padding: var(--sp-2) var(--sp-3); text-align: left; font-size: var(--fs-sm); }
.blog-post table th { background: var(--color-bg-alt); }
.blog-post__related { margin-top: var(--sp-10); padding-top: var(--sp-6); border-top: 1px solid var(--color-border); }

/* Alpine */
[x-cloak] { display: none !important; }

/* ATS Checker */
.ats-tool { display: flex; flex-direction: column; gap: var(--sp-5); margin-bottom: var(--sp-8); }
.ats-tool__tabs { display: flex; gap: var(--sp-2); border-bottom: 1px solid var(--color-border); }
.ats-tool__tab {
    background: none; border: none; border-bottom: 2px solid transparent;
    padding: var(--sp-3) var(--sp-1); margin-bottom: -1px; font-size: var(--fs-sm); font-weight: 600;
    color: var(--color-muted); cursor: pointer;
}
.ats-tool__tab--active { color: var(--color-primary); border-bottom-color: var(--color-primary); }
.ats-dropzone {
    border: 2px dashed var(--gray-300); border-radius: var(--radius-lg);
    padding: var(--sp-10) var(--sp-6); text-align: center; cursor: pointer; position: relative;
    background: var(--color-bg-alt);
    transition: border-color 0.15s, background 0.15s;
}
.ats-dropzone--dragging { border-color: var(--color-primary); background: var(--color-primary-subtle); }
.ats-dropzone p { margin: 0; color: var(--color-muted); }
.ats-dropzone__remove { background: none; border: none; color: var(--color-primary); cursor: pointer; font-size: var(--fs-sm); text-decoration: underline; }
.ats-dropzone__input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.ats-error { color: var(--color-error-text); font-size: var(--fs-sm); }

.ats-results { margin-top: var(--sp-10); padding-top: var(--sp-8); border-top: 1px solid var(--color-border); }
.ats-score { display: flex; justify-content: center; margin-bottom: var(--sp-8); }
.ats-score__dial {
    width: 10rem; height: 10rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
}
.ats-score__inner {
    width: 8rem; height: 8rem; border-radius: 50%; background: var(--color-bg);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    font-size: var(--fs-2xl); font-weight: 800; line-height: 1;
}
.ats-score__inner small { font-size: var(--fs-xs); font-weight: 500; color: var(--color-muted); margin-top: var(--sp-1); }

.ats-checks { display: flex; flex-direction: column; gap: var(--sp-3); }
.ats-check { border: 1px solid var(--color-border); border-left-width: 4px; border-radius: var(--radius-lg); padding: var(--sp-3) var(--sp-4); }
.ats-check--pass { border-left-color: var(--color-success); }
.ats-check--warn { border-left-color: var(--color-warn); }
.ats-check--fail { border-left-color: var(--color-error); }
.ats-check--skipped { border-left-color: var(--color-border); opacity: 0.7; }
.ats-check__head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.ats-check__badge { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; padding: 0.125rem var(--sp-2); border-radius: 999px; background: var(--color-bg-alt); }
.ats-check--pass .ats-check__badge { background: var(--color-success-bg); color: var(--color-success-text); }
.ats-check--warn .ats-check__badge { background: var(--color-warn-bg); color: var(--color-warn-text); }
.ats-check--fail .ats-check__badge { background: var(--color-error-bg); color: var(--color-error-text); }
.ats-check__label { font-weight: 600; }
.ats-check__points { margin-left: auto; font-size: var(--fs-xs); color: var(--color-muted); }
.ats-check__message { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); color: var(--color-muted); }

.ats-keywords { margin-top: var(--sp-8); }
.ats-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.ats-chip { font-size: var(--fs-xs); padding: var(--sp-1) var(--sp-3); border-radius: 999px; }
.ats-chip--missing { background: var(--color-error-bg); color: var(--color-error-text); }
.ats-chip--matched { background: var(--color-success-bg); color: var(--color-success-text); }

.ats-faq .faq-item { margin-bottom: var(--sp-5); }
.ats-related { margin-top: var(--sp-6); font-size: var(--fs-sm); }

.bullet-card { border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: var(--sp-4); margin-bottom: var(--sp-4); }
.bullet-card__original { color: var(--color-muted); margin: 0 0 var(--sp-2); }
.bullet-card__improved { margin: 0 0 var(--sp-3); }
.summary-rewrite { border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: var(--sp-4); }

.interview-accordion { display: flex; flex-direction: column; gap: var(--sp-3); }
.interview-accordion__item { border: 1px solid var(--color-border); border-radius: var(--radius-lg); overflow: hidden; }
.interview-accordion__head {
    width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
    padding: var(--sp-4); background: none; border: none; text-align: left; font-weight: 600; cursor: pointer;
}
.interview-accordion__item--open .interview-accordion__head { background: var(--color-bg-alt); }
.interview-accordion__body { padding: 0 var(--sp-4) var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-2); }
.interview-accordion__body p { margin: 0; }

.tracker-features { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-8); }
.tracker-feature h2 { font-size: var(--fs-md); margin-bottom: var(--sp-2); }
.tracker-feature p { color: var(--color-muted); margin: 0; }

.tracker-header { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); }

.tracker-board { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--sp-4); align-items: start; }
.tracker-column__title { font-size: var(--fs-sm); margin: 0 0 var(--sp-3); }
.tracker-column__list { display: flex; flex-direction: column; gap: var(--sp-3); min-height: 3rem; background: var(--color-bg-alt); border-radius: var(--radius-lg); padding: var(--sp-2); }
.tracker-card { background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: var(--sp-3); cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s; }
.tracker-card:hover { border-color: var(--color-primary); box-shadow: var(--shadow-sm); }
.tracker-card p { margin: 0; }
.tracker-card__position { font-weight: 600; font-size: var(--fs-sm); }
.tracker-card__company { color: var(--color-muted); font-size: var(--fs-sm); }
.tracker-card__location { color: var(--color-muted); font-size: var(--fs-xs); margin-top: var(--sp-1); }
.tracker-card__date { color: var(--color-muted); font-size: var(--fs-xs); margin-top: var(--sp-2); }

.tracker-modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; }
.tracker-modal__backdrop { position: absolute; inset: 0; background: rgba(17, 24, 39, 0.45); }
.tracker-modal__box { position: relative; background: var(--color-bg); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: var(--sp-6); width: 100%; max-width: 30rem; max-height: 90vh; overflow-y: auto; }
.tracker-modal__box h2 { margin-top: 0; }
.tracker-modal__actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-5); }

@media (max-width: 900px) {
    .tracker-board { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tracker-features { grid-template-columns: 1fr; }
}

@media (max-width: 359px) {
    /* Below 360px a two-up card is under ~150px wide — the preview stops
       being legible, so fall back to a single column. */
    .template-grid { grid-template-columns: 1fr; }
    .template-show__others ul { grid-template-columns: 1fr; }
}

@media (max-width: 600px) {
    /* Two kanban columns at 390px leave ~170px per card — one column reads. */
    .tracker-board { grid-template-columns: 1fr; }
    .tracker-modal__actions { flex-wrap: wrap; }
    .tracker-modal__box { padding: var(--sp-5) var(--sp-4); }
}

/* Profile guide pages (/fr/modeles-cv + /fr/{slug}) */
.profile-guide__intro p { margin-bottom: var(--sp-4); }
.profile-guide h2 { margin-top: var(--sp-8); margin-bottom: var(--sp-3); }
.profile-guide p { margin-bottom: var(--sp-4); }
.profile-guide__cta, .article-cta {
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap;
    background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
    padding: var(--sp-5); margin: var(--sp-6) 0;
}
.profile-guide__cta p, .article-cta p { margin: 0; font-weight: 600; }

.profile-accordion { display: flex; flex-direction: column; gap: var(--sp-3); }
.profile-accordion__item { border: 1px solid var(--color-border); border-radius: var(--radius-lg); overflow: hidden; }
.profile-accordion__button {
    width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
    padding: var(--sp-4); background: none; border: none; text-align: left; font-weight: 600;
    font-size: var(--fs-md); cursor: pointer;
}
.profile-accordion__button:hover { background: var(--color-bg-alt); }
.profile-accordion__icon { font-size: var(--fs-lg); color: var(--color-primary); transition: transform 0.15s; }
.profile-accordion__icon.is-open { transform: rotate(45deg); }
.profile-accordion__panel { padding: 0 var(--sp-4) var(--sp-5); }
.profile-accordion__panel p:last-child { margin-bottom: 0; }

/* In-article table of contents (views/partials/article-toc.php). Same
   bordered/rounded card language as .profile-accordion__item. */
.article-toc {
    border: 1px solid var(--color-border); border-radius: var(--radius-lg);
    background: var(--color-bg-alt); padding: var(--sp-4) var(--sp-5); margin: var(--sp-6) 0;
}
.article-toc__summary { font-weight: 600; cursor: pointer; }
.article-toc__summary::marker { color: var(--color-primary); }
.article-toc__list { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.article-toc__list a { font-size: var(--fs-sm); }

/* Visible breadcrumbs (views/partials/breadcrumbs.php) — the same
   BreadcrumbList JSON-LD SchemaService::breadcrumbList() already built,
   rendered on-page for the first time. */
.breadcrumbs { margin-bottom: var(--sp-4); }
.breadcrumbs__list { list-style: none; display: flex; flex-wrap: wrap; margin: 0; padding: 0; font-size: var(--fs-xs); color: var(--color-muted); }
.breadcrumbs__item { display: flex; align-items: center; gap: var(--sp-2); }
.breadcrumbs__sep { margin: 0 var(--sp-1); }

.profile-sample {
    padding: var(--sp-8); border-top: 4px solid var(--color-primary);
}
.profile-sample__header { text-align: center; margin-bottom: var(--sp-6); }
.profile-sample__kicker {
    display: inline-block; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--color-primary); margin-bottom: var(--sp-2);
}
.profile-sample__name { margin: 0; }
.profile-sample__title { color: var(--color-muted); margin: var(--sp-1) 0 0; }
.profile-sample__block { margin-bottom: var(--sp-5); }
.profile-sample__block h3 { font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-muted); margin-bottom: var(--sp-2); }
.profile-sample__list { list-style: none; display: flex; flex-direction: column; gap: var(--sp-2); }
.profile-sample__dates { display: block; font-size: var(--fs-xs); color: var(--color-muted); }
.profile-sample__tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.profile-sample__tag { background: var(--color-primary-subtle); color: var(--color-primary); font-size: var(--fs-xs); font-weight: 600; padding: var(--sp-1) var(--sp-3); border-radius: 999px; }
.profile-sample__cta { text-align: center; margin-top: var(--sp-6); }

.profile-also-for { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); }
.profile-also-for li { background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: 999px; padding: var(--sp-1) var(--sp-3); font-size: var(--fs-sm); }

.profile-related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--sp-4); }
.profile-related-card { display: block; padding: var(--sp-4); font-weight: 600; color: var(--color-text); }
.profile-related-card:hover { color: var(--color-primary); text-decoration: none; }

/* Related content — bottom of blog posts and profile pages (shared partial:
   views/partials/related-content.php). Same card family as .template-card
   and .profile-related-card, extended with an excerpt line. */
.related-content__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--sp-4); }
.related-content__card { display: block; padding: var(--sp-4); color: var(--color-text); }
.related-content__card:hover { color: var(--color-primary); text-decoration: none; }
.related-content__title { margin: 0 0 var(--sp-2); font-size: var(--fs-md); }
.related-content__excerpt { margin: 0; font-size: var(--fs-sm); color: var(--color-muted); font-weight: 400; }

.profile-faq .faq-item { margin-bottom: var(--sp-5); }

/* ======================================================================
   Focus-visible — keyboard-only focus rings on site chrome.
   MOBILE-AUDIT.md backlog item 7.

   Deliberately an explicit selector list rather than a blanket
   `a:focus-visible, button:focus-visible`: a blanket rule would reach inside
   .resume-page, which is frozen for mPDF parity (and whose contenteditable
   fields would then paint a ring the PDF never sees). Same ground rule as the
   responsive shell block above.
   ====================================================================== */
.navbar__burger:focus-visible,
.navbar__brand:focus-visible,
.navbar__links a:focus-visible,
.navbar__dropdown-btn:focus-visible,
.navbar__dropdown-menu a:focus-visible,
.lang-switcher a:focus-visible,
.footer a:focus-visible,
.template-card a:focus-visible,
.template-filter:focus-visible,
.tracker-card:focus-visible,
.tracker-modal__box a:focus-visible,
.faq-item summary:focus-visible,
.builder__viewbtn:focus-visible,
.builder__more-btn:focus-visible,
.tpl-slider__nav:focus-visible,
.tpl-slider__clear:focus-visible,
.builder__photo-btn:focus-visible,
.builder__photo-remove:focus-visible,
.builder__ats-badge:focus-visible,
.builder__sample-notice-close:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* The nav panel is a modal-ish overlay at mobile widths, so give the trapped
   focus somewhere obvious to land. */
@media (max-width: 768px) {
    .navbar__links a:focus-visible {
        outline-offset: -2px;
    }
}

/* Cookie consent banner. Rendered with [hidden] and revealed by site.js only
   when no choice is stored, so a visitor who has already answered never sees a
   flash of it on the next page load. */
.consent-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 200;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.75rem 1.5rem;
    padding: 1rem 1.25rem;
    background: #fff;
    border-top: 1px solid #e2e8f0;
    box-shadow: 0 -2px 12px rgba(15, 23, 42, 0.08);
}

/* [hidden] alone loses to `display: flex`. */
.consent-banner[hidden] {
    display: none;
}

.consent-banner__text {
    margin: 0;
    max-width: 60ch;
    font-size: 0.9rem;
    line-height: 1.5;
}

.consent-banner__actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

@media (max-width: 600px) {
    .consent-banner {
        justify-content: stretch;
    }

    .consent-banner__actions {
        width: 100%;
    }

    .consent-banner__actions .btn {
        flex: 1;
    }
}

/* Article cover images ----------------------------------------------------- */
/* aspect-ratio matches CoverImageService's 1200x630 output, so the box is
   reserved at the right shape before the image loads even on the paste-a-URL
   path, where the <img> carries no width/height attributes. */
.blog-post__cover, .profile-guide__cover { margin: 0 0 var(--sp-6); }
.blog-post__cover img, .profile-guide__cover img,
.blog-list__cover img {
    width: 100%;
    height: auto;
    aspect-ratio: 1200 / 630;
    object-fit: cover;
    border-radius: var(--radius-lg);
    display: block;
}
.blog-list__cover { display: block; margin-bottom: var(--sp-4); }

/* Blog two-column layout + sidebar ----------------------------------------- */
/*
   Shared by /blog, /fr/blog and /blog/{slug} (views/blog/index.php,
   views/blog/single.php, views/partials/blog-sidebar.php).

   The column split is derived from the existing scale rather than invented:
   .container is --content-max (1100px), the sidebar is a fixed 20rem (320px)
   and the gap is --sp-12 (48px), which leaves the main column ~732px — within
   a dozen pixels of the --content-max-narrow (720px) measure the article used
   as a single column. The article's line length is therefore preserved, not
   re-tuned, which is why the ratio is ~68/32 rather than a rounder number.

   minmax(0, 1fr) rather than 1fr on the main column: a grid item's default
   min-width is auto, so one wide element inside the article — a <pre> block or
   the .table-scroll wrapper site.js adds around every .blog-post table — would
   otherwise refuse to shrink and push the sidebar off the grid.
*/
.blog-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: var(--sp-12);
    align-items: start;
}
.blog-layout__main { min-width: 0; }

/* Sticky only where there is room for it to be useful, and only on pointer
   devices with the height to spare — a sticky sidebar on a short viewport
   just eats the screen. Top offset is the navbar's own height (3.5rem,
   .navbar__inner) plus a breathing gap, so the sticky sidebar settles just
   below the sticky navbar instead of scrolling underneath it (both are
   `position: sticky; top: 0`-adjacent, so without this the sidebar would
   rest partly behind the navbar's z-index: 100). max-height + overflow-y
   caps the sidebar at the remaining viewport so a sidebar taller than the
   screen scrolls internally instead of overflowing past the fold. */
.blog-aside { display: flex; flex-direction: column; gap: var(--sp-5); }
@media (min-width: 769px) and (min-height: 700px) {
    .blog-aside {
        position: sticky;
        top: calc(3.5rem + var(--sp-4));
        max-height: calc(100vh - 3.5rem - var(--sp-8));
        overflow-y: auto;
    }
}

/* Cards reuse the shared .card component so the sidebar reads as the same
   system as the templates gallery and the blog list. The hover lift is
   suppressed: .card:hover translates on Y, which is right for a clickable
   gallery tile and wrong for a static container the reader's pointer crosses
   on the way to a link inside it. */
.blog-aside__card { padding: var(--sp-5); }
.blog-aside__card:hover { transform: none; box-shadow: var(--shadow-sm); }

.blog-aside__title {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-muted);
    font-weight: 600;
    margin-bottom: var(--sp-4);
}

.blog-aside__search { display: flex; gap: var(--sp-2); }
.blog-aside__search input {
    flex: 1;
    min-width: 0;
    padding: var(--sp-2) var(--sp-3);
    font: inherit;
    font-size: var(--fs-sm);
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}
.blog-aside__search input:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
    border-color: var(--color-primary);
}

.blog-aside__list, .blog-aside__tools { list-style: none; display: flex; flex-direction: column; gap: var(--sp-4); }
.blog-aside__tools { gap: var(--sp-3); }
.blog-aside__list a { font-size: var(--fs-sm); font-weight: 500; line-height: 1.4; display: block; }
.blog-aside__date { display: block; font-size: var(--fs-xs); color: var(--color-muted); margin-top: var(--sp-1); }
.blog-aside__tools a { font-size: var(--fs-sm); }
.blog-aside__cta { display: block; text-align: center; margin-top: var(--sp-5); }
.blog-aside__cta:hover { text-decoration: none; }

.blog-post__back { margin-top: var(--sp-10); padding-top: var(--sp-6); border-top: 1px solid var(--color-border); }

/* Search results page */
.search-form { display: flex; gap: var(--sp-3); margin-top: var(--sp-6); max-width: 32rem; }
.search-form input {
    flex: 1;
    min-width: 0;
    padding: var(--sp-3) var(--sp-4);
    font: inherit;
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}
.search-form input:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
    border-color: var(--color-primary);
}
.search-note { color: var(--color-muted); margin-bottom: var(--sp-6); }
.search-results { display: flex; flex-direction: column; gap: var(--sp-4); }
.search-result { padding: var(--sp-5); }
.search-result:hover { transform: none; box-shadow: var(--shadow-sm); }
.search-result__title { font-size: var(--fs-md); margin-bottom: var(--sp-2); }
.search-result__meta { display: flex; gap: var(--sp-3); font-size: var(--fs-xs); color: var(--color-muted); margin-bottom: var(--sp-2); }
.search-result__type {
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    color: var(--color-primary);
}

/*
   Single column below the site's standard 768px breakpoint. The sidebar STACKS
   BELOW the article rather than being hidden: search and the tool links are
   the most useful things on the page on a phone, where there is no room for a
   long scan back up to the navbar. Source order already puts the sidebar last,
   so the stack needs no grid-row juggling — which is also why the sidebar is
   after the main column in the markup rather than before it.
*/
@media (max-width: 768px) {
    .blog-layout { grid-template-columns: 1fr; gap: var(--sp-8); }
    .blog-aside { position: static; }
    .search-form { flex-direction: column; }
}
