/* ============================================================================
   custom.css — Utility classes.
   Compose layouts inline: <div class="flex justify-between gap-md">…</div>
   Mirrors the dankstocks utility set so the two apps share the same
   shorthand vocabulary.
   ============================================================================ */

/* ── Web font ──────────────────────────────────────────────────────────────
   Urbanist @font-face is declared HERE (not only in tokens.css) so EVERY shell
   that loads custom.css gets the brand font — including the lightweight
   marketing shell, which does NOT load tokens.css. Without this the marketing
   nav wordmark silently fell back to Plus Jakarta Sans and rendered ~12px wider
   than the real Urbanist used on /login/, so the brand changed width across
   shells. Keep in sync with tokens.css. */
@font-face {
    font-family: 'Urbanist';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/assets/fonts/urbanist/Urbanist-Variable.woff2') format('woff2-variations'),
         url('/assets/fonts/urbanist/Urbanist-Variable.woff2') format('woff2');
}

/* Plus Jakarta Sans is self-hosted too (TQ100843) — the render-blocking
   fonts.googleapis.com/css2 stylesheet cost ~1.4s on the mobile critical path
   (PSI). Variable wght 200-800 covers every weight the public shells request
   (400-800). Subsets mirror Google's unicode-range split so the browser only
   downloads what it renders (latin in practice). The app shell (header.cfm)
   still uses Google Fonts: it needs italics + JetBrains Mono and already
   loads them async. Keep these files in sync if the family version bumps. */
@font-face {
    font-family: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 200 800;
    font-display: swap;
    src: url('/assets/fonts/jakarta/PlusJakartaSans-Variable-latin.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: 'Plus Jakarta Sans';
    font-style: normal;
    font-weight: 200 800;
    font-display: swap;
    src: url('/assets/fonts/jakarta/PlusJakartaSans-Variable-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Accessibility ─────────────────────────────────────────────────────────
   Skip link (WCAG 2.4.1), screen-reader-only utility, and a global keyboard
   focus indicator (WCAG 2.4.7). :focus-visible only paints for keyboard / AT
   users, so mouse clicks stay ring-free. Lives here in custom.css so every
   shell (app, marketing, auth, legal) inherits it — the marketing shell does
   not load tokens.css, hence the literal #0d9488 fallbacks on var(--accent). */
.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 {
    position: fixed; top: -60px; left: 8px; z-index: 100000;
    background: var(--accent, #0d9488); color: #fff;
    padding: 10px 16px; border-radius: 0 0 8px 8px;
    font-weight: 600; font-size: 14px; text-decoration: none;
    transition: top 0.15s ease;
}
.skip-link:focus { top: 0; }
:focus-visible {
    outline: 2px solid var(--accent, #0d9488);
    outline-offset: 2px;
    border-radius: 2px;
}
/* Container jump-targets (skip link lands on #viewArea) should move focus
   without painting a full-width outline box. */
#viewArea:focus { outline: none; }

/* ── Display ───────────────────────────────────────────────────────────── */
.hide, .none           { display: none !important; }
.show, .block          { display: block !important; }
.inline, .show-inline  { display: inline !important; }
.inline-block          { display: inline-block; }
.unset                 { display: unset; }
.clear                 { clear: both; }

/* ── Flex & Grid ───────────────────────────────────────────────────────── */
.flex                  { display: flex; }
.flex-col              { display: flex; flex-direction: column; }
.flex-row              { display: flex; flex-direction: row; }
.flex-wrap             { flex-wrap: wrap; }
.flex-nowrap           { flex-wrap: nowrap; }
.flex-form             { display: flex; align-items: center; }
.flex-1                { flex: 1; }
.flex-auto             { flex: 0 0 auto; }
.flex-shrink-0         { flex-shrink: 0; }
.justify-between, .between { justify-content: space-between; }
.justify-around        { justify-content: space-around; }
.justify-center        { justify-content: center; }
.justify-start         { justify-content: flex-start; }
.justify-end           { justify-content: flex-end; }
.align-center, .center { align-items: center; }
.align-start           { align-items: flex-start; }
.align-end             { align-items: flex-end; }
.align-baseline        { align-items: baseline; }
.self-center           { align-self: center; }
.grid                  { display: grid; }
.gap-xs                { gap: 4px; }
.gap-sm                { gap: 8px; }
.gap-md                { gap: 16px; }
.gap-lg                { gap: 24px; }
.gap-xl                { gap: 32px; }

/* ── Positioning ───────────────────────────────────────────────────────── */
.relative              { position: relative; }
.absolute              { position: absolute; }
.fixed                 { position: fixed; }
.sticky                { position: sticky; }
.float-left            { float: left; }
.float-right           { float: right; }
.l0                    { left: 0; }
.r0                    { right: 0; }
.t0                    { top: 0; }
.b0                    { bottom: 0; }
.l8                    { left: 8px; }
.r8                    { right: 8px; }
.t8                    { top: 8px; }
.b8                    { bottom: 8px; }
.l50                   { left: 50%; }
.r50                   { right: 50%; }
.t50                   { top: 50%; }
.b50                   { bottom: 50%; }

/* ── Spacing helpers (vertical-rhythm "spacers") ───────────────────────── */
.spacer-tiny           { margin: 3px 0; }
.spacer-small          { margin: 15px 0; }
.spacer                { margin: 30px 0; }
.spacer-large          { margin: 50px 0; }
.spacer-huge           { margin: 70px 0; }

/* ── Margin / padding ──────────────────────────────────────────────────── */
.mx-auto               { margin-left: auto; margin-right: auto; }
.m0                    { margin: 0; }
.m5                    { margin: 5px; }
.m10                   { margin: 10px; }
.m20                   { margin: 20px; }
.m30                   { margin: 30px; }
.mb0                   { margin-bottom: 0; }
.mb5                   { margin-bottom: 5px; }
.mb10                  { margin-bottom: 10px; }
.mb20                  { margin-bottom: 20px; }
.mt0                   { margin-top: 0; }
.mt5                   { margin-top: 5px; }
.mt10                  { margin-top: 10px; }
.mt20                  { margin-top: 20px; }
.p0                    { padding: 0; }
.p5                    { padding: 5px; }
.p10                   { padding: 10px; }
.p20                   { padding: 20px; }

/* ── Width / height ────────────────────────────────────────────────────── */
.w100                  { width: 100%; }
.w75                   { width: 75%; }
.w50                   { width: 50%; }
.w25                   { width: 25%; }
.w-auto                { width: auto; }
.h100                  { height: 100%; }
.h75                   { height: 75%; }
.h50                   { height: 50%; }
.h25                   { height: 25%; }
.h-auto                { height: auto; }
.h-screen              { height: 100vh; }
.min-h-screen          { min-height: 100vh; }

/* ── Cursor & interaction ──────────────────────────────────────────────── */
.pointer               { cursor: pointer; }
.pointer-none          { cursor: none; }
.disabled-click        { pointer-events: none; }
.user-select-none      { user-select: none; }

/* ── Overflow ──────────────────────────────────────────────────────────── */
.overflow-hidden       { overflow: hidden; }
.overflow-auto         { overflow: auto; }
.overflow-scroll       { overflow: scroll; }
.overflow-x-hidden     { overflow-x: hidden; }
.overflow-y-hidden     { overflow-y: hidden; }
.overflow-y-auto       { overflow-y: auto; }

/* ── Borders & outlines ────────────────────────────────────────────────── */
.no-border             { border: none; }
.no-outline            { outline: none; }
.rounded               { border-radius: var(--radius); }
.rounded-lg            { border-radius: var(--radius-lg); }
.rounded-full          { border-radius: 999px; }

/* ── Text ──────────────────────────────────────────────────────────────── */
.text-left             { text-align: left; }
.text-center           { text-align: center; }
.text-right            { text-align: right; }
.text-justify          { text-align: justify; }
.bold                  { font-weight: bold; }
.italic                { font-style: italic; }
.underline             { text-decoration: underline; }
.no-underline          { text-decoration: none; }
.uppercase             { text-transform: uppercase; }
.lowercase             { text-transform: lowercase; }
.capitalize            { text-transform: capitalize; }
.truncate              { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Font sizes (percentages — composable on top of body 14px) */
.fs88                  { font-size: 88%; }
.fs125                 { font-size: 125%; }
.fs150                 { font-size: 150%; }
.fs200                 { font-size: 200%; }
.fs300                 { font-size: 300%; }

/* ── Brand-aligned colors (token-driven) ───────────────────────────────── */
.clr-ink               { color: var(--ink); }
.clr-ink-60            { color: var(--ink-60); }
.clr-ink-40            { color: var(--ink-40); }
.clr-accent            { color: var(--accent); }
.clr-red               { color: var(--red); }
.clr-amber             { color: var(--amber); }
.clr-green             { color: var(--green); }
.clr-blue              { color: var(--blue); }
.clr-white             { color: var(--white); }

.bg-white              { background: var(--white); }
.bg-surface            { background: var(--surface); }
.bg-ink-02             { background: var(--ink-02); }
.bg-ink-05             { background: var(--ink-05); }
.bg-accent             { background: var(--accent); }
.bg-accent-muted       { background: var(--accent-muted); }
.bg-red-light          { background: var(--red-light); }
.bg-green-light        { background: var(--green-light); }
.bg-amber-light        { background: var(--amber-light); }
.bg-blue-light         { background: var(--blue-light); }

/* ── Visibility helpers ────────────────────────────────────────────────── */
.invisible             { visibility: hidden; }
.visible               { visibility: visible; }
.opacity-0             { opacity: 0; }
.opacity-50            { opacity: 0.5; }
.opacity-100           { opacity: 1; }
.transparent           { opacity: 0.5; }

/* ── Effects ───────────────────────────────────────────────────────────── */
.grow                  { transition: transform .2s; }
.grow:hover            { transform: scale(1.05); }
.shadow-sm             { box-shadow: var(--shadow-sm); }
.shadow-md             { box-shadow: var(--shadow-md); }
.shadow-lg             { box-shadow: var(--shadow-lg); }
