/*
Theme Name: Cashmere Marketing
Theme URI: https://trustdavid.co.za
Author: TrustDavid
Description: Cashmere Marketing — built on the TrustDavid Timber/Twig scaffold.
Version: 0.1.0
Requires at least: 6.8
Requires PHP: 8.2
License: Proprietary
Text Domain: td-base
*/

/* ==========================================================================
   TOKENS

   ⚠ TWO RULES, AND THE SECOND IS THE ONE THAT ROTS IF IGNORED.

   1. PRIMITIVES are raw values. SEMANTIC tokens name a value by its JOB and
      must REFERENCE a primitive, never restate a hex. A restated hex drifts:
      on RDCM three colours were each declared twice, same value, under two
      names, in two files, and the duplicates diverged before anyone noticed.

   2. There is ONE token home — this file. A second `:root` in a component
      stylesheet is how the above happened.

   The values below are NEUTRAL PLACEHOLDERS. bin/init-site.sh does not touch
   them; a build replaces them with the client's real palette and type as its
   first styling act. Nothing here is a design.

   ACCESSIBILITY NOTE, carried from a real audit: check contrast on the actual
   pairing before shipping a colour. RDCM's accent measured 4.31:1 on its page
   background and missed AA for normal text by 0.19 — fixed by darkening 1.2%
   in lightness with hue and saturation held, the smallest change that cleared
   the bar. Eyeballing does not catch a 0.19 miss.
   ========================================================================== */

:root {
    /* --- Primitives ------------------------------------------------------
     * Sampled from her live site, not chosen. The gold is the dominant
     * non-grey pixel in the logo (291,801 px). Contrast measured on black:
     *   gold #B09048 .... 6.93:1  AA, body-safe
     *   grey #939598 .... 6.99:1  AA — her value, LIFTED, see below
     *   grey #666666 .... 3.66:1  ⛔ FAILS AA — on her current site, not used here
     *
     * ⚠ THE LIFT, and why the number was not the whole story. #939598 PASSES AA
     * at 6.99:1, and it still read thin on screen. WCAG's ratio measures colour
     * only — it has no term for STROKE WEIGHT, and light 300-weight type on a
     * dark ground loses perceived contrast the formula cannot see. David called
     * it off the render; the render was right and the number was incomplete.
     * Fixed on both axes at once: weight 300 → 400, and the grey lifted to
     * #D0D2D5 (13.86:1, AAA). Her hue is preserved — this is her grey brighter,
     * not a neutral substitute.
     */
    --td-c-black:   #000000;   /* her page ground — true black, not near-black */
    --td-c-ink:     #0A0A0A;   /* lifted surface, only just off the ground */
    --td-c-line:    #262626;   /* hairline rules and field borders */
    --td-c-grey:    #D0D2D5;   /* her body grey, lifted — 13.86:1 AAA */
    --td-c-grey-lo: #939598;   /* her original grey — de-emphasised UI, 6.99:1 AA */
    --td-c-grey-hi: #EDEEEF;   /* headings — 18.6:1 */
    --td-c-white:   #FFFFFF;
    --td-c-gold:    #B09048;   /* measured from the logo */
    --td-c-gold-hi: #C9A85C;   /* hover — lifted, 8.9:1 */

    /* --- Semantic (reference the primitives above, never a raw value) ---- */
    --td-color-background:    var(--td-c-black);
    --td-color-surface:       var(--td-c-ink);
    --td-color-border:        var(--td-c-line);
    --td-color-text:          var(--td-c-grey);
    --td-color-text-muted:    var(--td-c-grey-lo);
    --td-color-heading:       var(--td-c-grey-hi);
    --td-color-link:          var(--td-c-gold);
    --td-color-link-hover:    var(--td-c-gold-hi);

    /* --- Type ------------------------------------------------------------
     * ONE family, self-hosted. Her live site pulls Open Sans, Montserrat AND
     * Helvetica from Google's CDN — three families for forty words. The
     * wordmark is inside the logo image, so no display face is needed.
     *
     * ⚠ ONE WEIGHT ONLY — 400. The 300 was dropped after it read thin on the
     * dark ground (see the colour note above). One file, 42KB, latin subset.
     * Her original site sets 500; 400 with the lifted grey lands in the same
     * place optically without a second download.
     */
    --td-font-body:    'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --td-font-ui:      var(--td-font-body);
    --td-font-display: var(--td-font-body);

    --td-size-h1:   clamp(2rem, 5vw, 3.25rem);
    --td-size-h2:   clamp(1.5rem, 3.5vw, 2.25rem);
    --td-size-h3:   1.375rem;
    --td-size-body: 1.125rem;
    --td-size-ui:   0.875rem;
    --td-size-meta: 0.75rem;

    /* --- Space ----------------------------------------------------------- */
    --td-space-xs: 0.5rem;
    --td-space-sm: 1rem;
    --td-space-md: 1.5rem;
    --td-space-lg: 2.5rem;
    --td-space-xl: 4rem;
    --td-space-xxl: 6rem;

    /* --- Measure --------------------------------------------------------- */
    --td-measure:       65ch;   /* the reading column */
    --td-width-content: 46rem;
    --td-width-wide:    72rem;

    --td-radius: 2px;
    --td-transition: 0.3s ease;
}

/* ==========================================================================
   BASE — the minimum that makes a document readable. Not a design.
   ========================================================================== */

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

body {
    margin: 0;
    background: var(--td-color-background);
    color: var(--td-color-text);
    font-family: var(--td-font-body);
    font-size: var(--td-size-body);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--td-font-display);
    color: var(--td-color-heading);
    line-height: 1.2;
}

h1 { font-size: var(--td-size-h1); }
h2 { font-size: var(--td-size-h2); }
h3 { font-size: var(--td-size-h3); }

a { color: var(--td-color-link); transition: color var(--td-transition); }

img { max-width: 100%; height: auto; display: block; }

/* Screen-reader-only, plus the skip link that becomes visible on focus.
   Both are accessibility floor, not decoration — an audit asks for them. */
.screen-reader-text {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.td-skip-link:focus {
    position: fixed; top: 0; left: 0; z-index: 100000;
    width: auto; height: auto; margin: 0; padding: var(--td-space-sm);
    clip: auto; clip-path: none;
    background: var(--td-color-background); color: var(--td-color-text);
}

/* ==========================================================================
   LAYOUT PRIMITIVES

   These are the only "styles" the scaffold ships, and they are here because
   without them the MODULES DO NOT FUNCTION — masonry has no columns, full-bleed
   does not bleed. Everything decorative belongs to the site, not here.
   ========================================================================== */

.td-main { display: block; }

.td-prose { max-width: var(--td-measure); }
.td-prose > :first-child { margin-top: 0; }
.td-prose > :last-child  { margin-bottom: 0; }

.td-module { margin: 0 auto var(--td-space-lg); max-width: var(--td-width-content); }

/* Image layouts. `full-bleed` uses the 50vw/-50% pair rather than `width:100vw`
   because 100vw includes the scrollbar and produces a horizontal scroll on
   Windows — a mobile audit catches it, but only after it ships. */
.td-module--image.is-inline        { max-width: var(--td-width-content); }
.td-module--image.is-three-quarter { max-width: var(--td-width-wide); }
.td-module--image.is-full-bleed {
    max-width: none;
    width: 100%;
    margin-left: 50%;
    transform: translateX(-50%);
    max-width: 100vw;
}

.td-caption {
    font-family: var(--td-font-ui);
    font-size: var(--td-size-meta);
    color: var(--td-color-text-muted);
    margin-top: var(--td-space-xs);
}
.td-caption_meta { display: block; }

/* Galleries. Grid is the DEFAULT and the safe one — see inc/gallery.php for
   why masonry is opt-in per gallery rather than global. */
.td-module--gallery { display: grid; gap: var(--td-space-sm); }
.td-module--gallery.is-two-up  { grid-template-columns: repeat(2, 1fr); }
.td-module--gallery.is-four-up { grid-template-columns: repeat(2, 1fr); }
.td-module--gallery.is-w-full  { max-width: var(--td-width-wide); }

.td-module--gallery.is-masonry {
    display: block;
    column-count: 2;
    column-gap: var(--td-space-sm);
}
.td-module--gallery.is-masonry .td-gallery_cell {
    break-inside: avoid;
    margin: 0 0 var(--td-space-sm);
}

.td-imagetext { display: block; }

.td-cards_list {
    list-style: none; margin: 0; padding: 0;
    display: grid; gap: var(--td-space-md);
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

/* --- Mobile first: the multi-column layouts above collapse below 48em ----- */
@media (max-width: 47.999em) {
    .td-module--gallery,
    .td-module--gallery.is-two-up,
    .td-module--gallery.is-four-up { grid-template-columns: 1fr; }
    .td-module--gallery.is-masonry { column-count: 1; }
}

@media (min-width: 48em) {
    .td-module--imagetext {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: var(--td-space-lg);
        align-items: center;
    }
    .td-module--imagetext.is-text-right .td-imagetext_text  { order: 2; }
    .td-module--imagetext.is-text-right .td-imagetext_media { order: 1; }
}
