/* Public pages — CORE-owned baseline (propagates with the template; apps must
 * NOT edit it — redesign in assets/public/css/site.css, which can override).
 * Loaded before site.css on every public page. Keep it tiny: only rules the
 * core's public chrome depends on regardless of the app's redesign. */

/* Skip to content (a11y, WCAG 2.4.1): first focusable of every public page,
   visible only while keyboard-focused. Logical properties = RTL-safe. */
.skip-link {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);   /* off-screen WITHOUT extending the page */
    white-space: nowrap;
    z-index: 100000;
    background: #2c3338;
    color: #f0f0f1;
    padding: 8px 14px;
    border-radius: 4px;
}
.skip-link:focus {
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    inset-inline-start: 8px;
    top: 8px;
}

/* Inline add-to-cart error (shop-cart.js — no native dialogs). */
.buy-msg { color: #d66a6a; font-size: .9rem; margin: 8px 0 0; }
.buy-msg:empty { display: none; }


/* ── styleguide chrome (/styleguide — page-model §8) ──
   Presentation of the module gallery only, never part of the library;
   lives here because the public CSP (style-src 'self') forbids inline
   <style> blocks in views. */
.sg-item { margin-block: 2rem; }
.sg-item > .sg-name { font: 600 .8rem/1 ui-monospace, monospace; letter-spacing: .06em;
    color: var(--mod-muted, #5a6172); text-transform: uppercase; margin-block-end: .75rem;
    padding-block-end: .4rem; border-block-end: 1px solid var(--mod-line, #e5e7ee); }

/* ── Public-zone error page (views/public/error.php) ──
   Neutral, token-driven: each site's site.css theme colors it via the
   --mod-* vars it already maps. */
.public-error { text-align: center; }
.public-error .m-inner { padding-block: calc(var(--mod-space, 24px) * 2); }
.public-error-code { margin: 0; font-size: clamp(4.5rem, 11vw, 8rem);
    line-height: 1; font-weight: 200; opacity: .22; }
.public-error h1 { margin: .2em 0 1em; font-weight: 400;
    font-size: clamp(1.3rem, 2.6vw, 1.8rem); }

/* ══════════ Cookie consent — core DEFAULT look ══════════
   The banner partial (views/public/cookie-consent.php) is core, so it must
   look presentable with ZERO app CSS: unstyled it rendered as a raw block
   glued under the footer (found on aloetherapy 2026-07-29). Themed via the
   --mod-* tokens (site.css overrides win — it loads after this file). */
.cookie-consent[hidden] { display: none; }
.cookie-consent {
    position: fixed; inset-block-end: 18px; inset-inline-start: 18px; z-index: 95;
    max-inline-size: 380px; padding: 18px 20px;
    border: 1px solid var(--mod-line, rgba(0, 0, 0, .12));
    border-radius: var(--mod-radius, 14px);
    background: var(--mod-surface, #fff); color: var(--mod-fg, #1c2430);
    box-shadow: 0 18px 44px -18px rgba(0, 0, 0, .35);
    font-size: .86rem; line-height: 1.55;
}
.cookie-consent__text { margin: 0 0 14px; }
.cookie-consent__text a { color: var(--mod-accent, inherit); text-decoration: underline; }
.cookie-consent__actions { display: flex; gap: 10px; }
.cookie-consent__actions button {
    flex: 1; padding: 9px 14px; border-radius: var(--mod-radius, 10px);
    font: inherit; font-size: .84rem; font-weight: 600; cursor: pointer;
}
.cookie-consent__accept { border: 0; background: var(--mod-accent, #1c2430); color: var(--mod-accent-fg, #fff); }
.cookie-consent__accept:hover { filter: brightness(1.08); }
.cookie-consent__decline { border: 1px solid var(--mod-line, rgba(0, 0, 0, .25)); background: transparent; color: inherit; }
.cookie-consent__decline:hover { border-color: currentColor; }
@media (max-width: 480px) {
    .cookie-consent { inset-inline: 12px; max-inline-size: none; }
}

/* ══════════ Enriched images — keep the box fluid ══════════
   media_enrich_imgs()/media_img() add intrinsic width/height for CLS. The
   height ATTRIBUTE is also a presentational hint (height: Npx), so a CSS
   that constrains only the width (width: 104px; aspect-ratio: 4/3 — olga's
   blog thumbs, 2026-07-29) suddenly got a fixed 500px tall box: a sliver.
   :where() = zero specificity: this beats the attribute hint (any author
   rule does) but loses to EVERY app rule; the UA still derives
   aspect-ratio from the attrs, so the CLS reservation survives. */
:where(img[width][height]) { height: auto; }
