/*
 * design-system.css
 * Personal design system — web component library
 *
 * Deployment structure required (paths relative to this CSS file):
 *   ../assets/fira-fonts/Fira_Sans/FiraSans-Regular.ttf
 *   ../assets/fira-fonts/Fira_Sans/FiraSans-Italic.ttf
 *   ../assets/fira-fonts/Fira_Sans/FiraSans-Medium.ttf
 *   ../assets/fira-fonts/Fira_Sans/FiraSans-MediumItalic.ttf
 *   ../assets/fira-fonts/Fira_Sans/FiraSans-SemiBold.ttf
 *   ../assets/fira-fonts/Fira_Sans/FiraSans-SemiBoldItalic.ttf
 *
 * Usage: <link rel="stylesheet" href="path/to/design-system.css">
 * No external network dependencies — fully offline-capable.
 *
 * Fonts included:
 *   Fira Sans — static TTFs (normal + italic)
 *   Weights used: 300 (light), 400 (regular), 500 (medium), 600 (semibold), 700 (bold)
 *   Weights available: 100–900 (thin → black), plus italics
 *
 * SwiftUI equivalents are noted in comments throughout.
 */


/* ============================================================
   1. FONTS
   ============================================================ */

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-Thin.ttf') format('truetype');
  font-weight: 100;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-ThinItalic.ttf') format('truetype');
  font-weight: 100;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-ExtraLight.ttf') format('truetype');
  font-weight: 200;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-ExtraLightItalic.ttf') format('truetype');
  font-weight: 200;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-Light.ttf') format('truetype');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-LightItalic.ttf') format('truetype');
  font-weight: 300;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-Italic.ttf') format('truetype');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-Medium.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-MediumItalic.ttf') format('truetype');
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-SemiBold.ttf') format('truetype');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-SemiBoldItalic.ttf') format('truetype');
  font-weight: 600;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-BoldItalic.ttf') format('truetype');
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-ExtraBold.ttf') format('truetype');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-ExtraBoldItalic.ttf') format('truetype');
  font-weight: 800;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-Black.ttf') format('truetype');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Sans';
  src: url('../assets/fira-fonts/Fira_Sans/FiraSans-BlackItalic.ttf') format('truetype');
  font-weight: 900;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Mono';
  src: url('../assets/fira-fonts/Fira_Mono/FiraMono-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Mono';
  src: url('../assets/fira-fonts/Fira_Mono/FiraMono-Medium.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Fira Mono';
  src: url('../assets/fira-fonts/Fira_Mono/FiraMono-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}


/* ============================================================
   2. COLOR TOKENS
   ============================================================ */

:root {

  /* --- Swatches 1–14 (inlined from assets/color-swatches.css) --- */
  /* Each swatch is a light/dark pair for use as fill + stroke/text */

  --swatch-1-light:  #e15d4b;  --swatch-1-dark:  #74423C;  /* Muted Crimson   */
  --swatch-2-light:  #d3854c;  --swatch-2-dark:  #694434;  /* Burnt Sienna    */
  --swatch-3-light:  #d9757f;  --swatch-3-dark:  #7D3A2F;  /* Dusty Rose      */
  --swatch-4-light:  #dd924b;  --swatch-4-dark:  #834724;  /* Caramel Brown   */
  --swatch-5-light:  #d7c465;  --swatch-5-dark:  #7b642b;  /* Prairie Gold    */
  --swatch-6-light:  #a1bf47;  --swatch-6-dark:  #656F34;  /* Olive Drab      */
  --swatch-7-light:  #daee6b;  --swatch-7-dark:  #7f952e;  /* Chartreuse      */
  --swatch-8-light:  #59e578;  --swatch-8-dark:  #3B7A40;  /* Sage Green      */
  --swatch-9-light:  #4ab75a;  --swatch-9-dark:  #275056;  /* Forest Green    */
  --swatch-10-light: #4bc6ac;  --swatch-10-dark: #4F6363;  /* Jungle Teal     */
  --swatch-11-light: #6cc8dd;  --swatch-11-dark: #37728f;  /* Steel Teal      */
  --swatch-12-light: #80F5F9;  --swatch-12-dark: #5c81ab;  /* Robin Egg Blue  */
  --swatch-13-light: #c999e9;  --swatch-13-dark: #775190;  /* Dusty Violet    */
  --swatch-14-light: #df93bf;  --swatch-14-dark: #87466A;  /* Mauve           */
  
  /* --- Warm gray scale (light mode) ---
   * Derived from palette warmth — slightly warm-tinted, not pure neutral.
   * Used for UI chrome, text, borders, and disabled states.
   */
  --gray-50:  #F7F7F5;
  --gray-100: #EBEBE8;
  --gray-200: #D4D4D0;
  --gray-300: #ADADAA;
  --gray-400: #888885;
  --gray-500: #606060;
  --gray-600: #4D4D4B;
  --gray-700: #3A3A38;
  --gray-900: #1A1A18;

  /* --- Global UI tokens — light mode --- */
  --background-fill: #FFFFFF;
  --panel-border:    #EBEBEB;
  --panel-color:     #FCFCFC;

  /* --- Semantic aliases --- */
  --color-text:          #312e2c;  /* Body — warm near-black (= gray-900)    */
  --color-text-secondary:#7A5E45;  /* Meta — warm brown (≥4.5:1 on light bg) */
  --color-text-disabled: var(--gray-400);
  --color-text-h1:       var(--color-text);  /* Heading aliases — reserved for per-level color overrides */
  --color-text-h2:       var(--color-text);
  --color-text-h3:       var(--color-text);
  --color-bg:            var(--background-fill);
  --color-panel:         var(--panel-color);
  --color-border:        var(--panel-border);
  --color-border-input:  var(--gray-300);
  --color-focus:         var(--swatch-11-light);  /* Steel Teal — safe across all swatches */
  --color-error:         var(--swatch-1-dark);
  --color-error-border:  var(--swatch-1-light);
  --color-checked:        var(--swatch-3-light);  /* Dusty Rose — swap to any swatch per form */
  --color-checked-border: var(--swatch-3-dark);
  --color-link:           "black";   /* Standard link — Olive Drab dark           */
  --color-link-accent:    var(--swatch-11-dark);  /* Accent/action link — Steel Teal dark      */
  --color-code:           var(--swatch-9-dark);   /* Inline/block code text — Forest Green     */

  /* Alert background tints (explicit rgba — no color-mix needed) */
  --alert-info-bg:    rgba(107, 187, 205, 0.10);  /* swatch-11-light #6BBBCD */
  --alert-success-bg: rgba(109, 195, 122, 0.10);  /* swatch-8-light  #6DC37A */
  --alert-warning-bg: rgba(200, 177, 90,  0.10);  /* swatch-5-light  #C8B15A */
  --alert-error-bg:   rgba(179, 88,  76,  0.10);  /* swatch-1-light  #B3584C */

  /* Focus ring tints — rgba of swatch-11 / swatch-1 for box-shadow rings */
  --color-focus-ring: rgba(107, 187, 205, 0.20);  /* swatch-11-light #6BBBCD */
  --color-error-ring: rgba(179, 88,  76,  0.20);  /* swatch-1-light  #B3584C */
}

/* --- Dark mode (explicit toggle via [data-theme="dark"]) --- */
[data-theme="dark"] {
  --gray-50:  #1A1918;
  --gray-100: #242220;
  --gray-200: #302E2B;
  --gray-300: #4A4845;
  --gray-400: #686663;
  --gray-500: #888885;
  --gray-600: #AEAEAA;
  --gray-700: #D4D4D0;
  --gray-900: #F7F7F5;

  --background-fill: #1A1918;
  --panel-border:    #302E2B;
  --panel-color:     #242220;

  --color-text:           #ede5e2;
  --color-text-secondary: #888885;
  --color-text-disabled:  #686663;
  --color-bg:             #1A1918;
  --color-panel:          #242220;
  --color-border:         #302E2B;
  --color-border-input:   #4A4845;
  --color-focus:          var(--swatch-11-light);
  --color-error:          var(--swatch-1-light);
  --color-error-border:   var(--swatch-1-light);
  --color-link:           "white";   /* Flip to light variant for dark bg contrast */
  --color-link-accent:    var(--swatch-11-light);
  --color-code:           var(--swatch-9-light);   /* Flip to light for dark bg readability     */
}

/* --- Dark mode (system preference fallback, no explicit theme set) --- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --gray-50:  #1A1918;
    --gray-100: #242220;
    --gray-200: #302E2B;
    --gray-300: #4A4845;
    --gray-400: #686663;
    --gray-500: #888885;
    --gray-600: #AEAEAA;
    --gray-700: #D4D4D0;
    --gray-900: #F7F7F5;

    --background-fill: #1A1918;
    --panel-border:    #302E2B;
    --panel-color:     #242220;

    --color-text:           #F7F7F5;
    --color-text-secondary: #888885;
    --color-text-disabled:  #686663;
    --color-bg:             #1A1918;
    --color-panel:          #242220;
    --color-border:         #302E2B;
    --color-border-input:   #4A4845;
    --color-focus:          var(--swatch-11-light);
    --color-error:          var(--swatch-1-light);
    --color-error-border:   var(--swatch-1-light);
    --color-link:           var(--swatch-6-light);
    --color-link-accent:    var(--swatch-11-light);
    --color-code:           var(--swatch-9-light);
  }
}


/* ============================================================
   3. TYPOGRAPHY
   ============================================================
   SwiftUI: Font / .font() modifier
   Fira Sans via @font-face above; system-ui fallback for early render.
   ============================================================ */

:root {
  --font-sans: 'Fira Sans', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'Fira Mono', ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace;

  /* Type scale */
  --text-xs:   0.75rem;    /* 12px — caption          */
  --text-sm:   0.875rem;   /* 14px — small, meta      */
  --text-base: 1rem;       /* 16px — body             */
  --text-lg:   1.125rem;   /* 18px                    */
  --text-xl:   1.25rem;    /* 20px — h4, post title   */
  --text-2xl:  1.5rem;     /* 24px — h3               */
  --text-3xl:  1.7rem;   /* 27.2px — h2             */
  --text-4xl:  2.25rem;    /* 36px — h1               */

  --leading-tight:  1.2;
  --leading-normal: 1.5;
  --leading-relaxed:1.7;
}


/* ============================================================
   4. SPACING & SIZING
   ============================================================
   8pt base grid. All values are multiples of 4px.
   SwiftUI: padding() / spacing in Stack
   ============================================================ */

:root {
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
}


/* ============================================================
   5. RESET / BASE
   ============================================================ */

*, *::before, *::after {
  box-sizing: border-box;
  margin: 2px 0;
  padding: 0;
}

html {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: var(--leading-normal);
  color: var(--color-text);
  background-color: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

body {
  min-height: 100vh;
  background-color: var(--color-bg);
  color: var(--color-text);
  transition: background-color 0.2s, color 0.2s;
}

h1 { font-size: var(--text-4xl); font-weight: 500; line-height: var(--leading-tight); color: var(--color-text-h1); }
h2 { font-size: var(--text-3xl); font-weight: 400; line-height: var(--leading-tight); color: var(--color-text-h2); }
h3 { font-size: var(--text-2xl); font-weight: 600; line-height: var(--leading-tight); color: var(--color-text-h3); }
h4 { font-size: var(--text-xl);  font-weight: 600; line-height: var(--leading-tight); }
h5 { font-size: var(--text-lg);  font-weight: 500; }
h6 { font-size: var(--text-base);font-weight: 500; }

p  { line-height: var(--leading-relaxed); }

a {
  color: var(--color-link);
  text-decoration: none;
  font-weight: 700;
}
a:hover        { text-decoration: underline; }
a:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

small { font-size: var(--text-sm); }

code, pre {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

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


/* ============================================================
   6. COMPONENTS
   ============================================================ */


/* --- 6.0 Window (overall app/page container) ---
 * SwiftUI:
 *   WindowGroup { content }
 *     — window chrome is OS-managed on macOS/iOS
 *   Web: outermost container wrapping the full page or app view
 * ---------------------------------------------------------- */

.window {
  background-color: var(--color-bg);
  border: 1px solid var(--color-border-input);
  border-radius: 11px;
  padding: 10px;
  transition: background-color 0.2s, border-color 0.2s;
}


/* --- 6.1 Panel ---
 * SwiftUI:
 *   RoundedRectangle(cornerRadius: 1)
 *     .fill(Color(.secondarySystemBackground))
 *     .overlay(RoundedRectangle(cornerRadius: 1).stroke(Color(.separator), lineWidth: 2))
 * ---------------------------------------------------------- */

.panel {
  background-color: var(--color-panel);
  border: 2px solid var(--color-border);
  border-radius: 1px;
  padding: 10px;
  transition: background-color 0.2s, border-color 0.2s;
}

.panel-flat {
  background-color: var(--color-panel);
  border: 2px solid var(--color-border);
  border-radius: 1px;
  padding: 10px;
  box-shadow: none;
  transition: background-color 0.2s, border-color 0.2s;
}


/* --- 6.2 Text Input ---
 * SwiftUI: TextField("Placeholder", text: $value)
 *   .textFieldStyle(.roundedBorder)
 * States: default, focus, disabled, error
 * ---------------------------------------------------------- */

.input {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--color-text);
  background-color: var(--color-panel);
  border: 1px solid var(--color-border-input);
  border-radius: 4px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
  -webkit-appearance: none;
  appearance: none;
}

.input::placeholder { color: var(--color-text-disabled); }

.input:focus {
  border-color: var(--color-focus);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.input:disabled {
  background-color: var(--gray-100);
  color: var(--color-text-disabled);
  cursor: not-allowed;
  opacity: 1;
}

.input.error {
  border-color: var(--color-error-border);
}

.input.error:focus {
  box-shadow: 0 0 0 3px var(--color-error-ring);
}


/* --- 6.3 Textarea ---
 * SwiftUI: TextEditor(text: $value) with border overlay
 * Same states as text input.
 * ---------------------------------------------------------- */

.textarea {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--color-text);
  background-color: var(--color-panel);
  border: 1px solid var(--color-border-input);
  border-radius: 4px;
  outline: none;
  resize: vertical;
  min-height: 100px;
  line-height: var(--leading-relaxed);
  transition: border-color 0.15s, box-shadow 0.15s;
  -webkit-appearance: none;
  appearance: none;
}

.textarea::placeholder { color: var(--color-text-disabled); }
.textarea:focus        { border-color: var(--color-focus); box-shadow: 0 0 0 3px var(--color-focus-ring); }
.textarea:disabled     { background-color: var(--gray-100); color: var(--color-text-disabled); cursor: not-allowed; }
.textarea.error        { border-color: var(--color-error-border); }


/* --- 6.4 Select / Dropdown ---
 * SwiftUI: Picker("Label", selection: $value) { ... }
 *   .pickerStyle(.menu)
 * States: default, focus, disabled
 * ---------------------------------------------------------- */

.select {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-6) var(--space-2) var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--color-text);
  background-color: var(--color-panel);
  border: 1px solid var(--color-border-input);
  border-radius: 4px;
  outline: none;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
  -webkit-appearance: none;
  appearance: none;
}

.select:focus    { border-color: var(--color-focus); box-shadow: 0 0 0 3px var(--color-focus-ring); }
.select:disabled { background-color: var(--gray-100); color: var(--color-text-disabled); cursor: not-allowed; }


/* --- Form field wrapper (label + input + helper/error text) ---
 * SwiftUI: VStack(alignment: .leading, spacing: 4) { Text(label); field; Text(helper) }
 * ---------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: var(--space-1); }
.field-label { font-size: var(--text-sm); font-weight: 500; color: var(--color-text); }
.field-helper { font-size: var(--text-xs); color: var(--color-text-secondary); }
.field-error  { font-size: var(--text-xs); color: var(--color-error); }


/* --- 6.5 Button ---
 * SwiftUI: Button("Label") { action() }
 *   .buttonStyle(.borderedProminent)
 * States: default, hover, active, focus-visible, disabled
 * Variants: default (dark), + one class per swatch (1–14)
 * ---------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 5px 10px;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: var(--leading-tight);
  border: none;
  border-radius: 4.5px;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s, box-shadow 0.15s, filter 0.15s;
  background-color: var(--gray-900);
  color: var(--gray-50);
  -webkit-appearance: none;
  appearance: none;
}

.btn:hover         { background-color: var(--gray-700); }
.btn:active        { background-color: var(--gray-900); box-shadow: inset 0 2px 4px rgba(0,0,0,0.25); }
.btn:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.btn:disabled,
.btn[disabled]     { background-color: var(--gray-200); color: var(--gray-400); cursor: not-allowed; box-shadow: none; filter: none; }

/* Outline variant */
.btn-outline {
  background-color: transparent;
  color: var(--color-text);
  border: 1px solid var(--color-border-input);
}
.btn-outline:hover  { background-color: var(--gray-100); }
.btn-outline:active { background-color: var(--gray-200); box-shadow: inset 0 1px 3px rgba(0,0,0,0.15); }

/* Swatch variants — light bg, dark text */
.btn-s1  { background-color: var(--swatch-1-light);  color: var(--swatch-1-dark);  }
.btn-s2  { background-color: var(--swatch-2-light);  color: var(--swatch-2-dark);  }
.btn-s3  { background-color: var(--swatch-3-light);  color: var(--swatch-3-dark);  }
.btn-s4  { background-color: var(--swatch-4-light);  color: var(--swatch-4-dark);  }
.btn-s5  { background-color: var(--swatch-5-light);  color: var(--swatch-5-dark);  }
.btn-s6  { background-color: var(--swatch-6-light);  color: var(--swatch-6-dark);  }
.btn-s7  { background-color: var(--swatch-7-light);  color: var(--swatch-7-dark);  }
.btn-s8  { background-color: var(--swatch-8-light);  color: var(--swatch-8-dark);  }
.btn-s9  { background-color: var(--swatch-9-light);  color: var(--swatch-9-dark);  }
.btn-s10 { background-color: var(--swatch-10-light); color: var(--swatch-10-dark); }
.btn-s11 { background-color: var(--swatch-11-light); color: var(--swatch-11-dark); }
.btn-s12 { background-color: var(--swatch-12-light); color: var(--swatch-12-dark); }
.btn-s13 { background-color: var(--swatch-13-light); color: var(--swatch-13-dark); }
.btn-s14 { background-color: var(--swatch-14-light); color: var(--swatch-14-dark); }

.btn-s1:hover,  .btn-s2:hover,  .btn-s3:hover,  .btn-s4:hover,
.btn-s5:hover,  .btn-s6:hover,  .btn-s7:hover,  .btn-s8:hover,
.btn-s9:hover,  .btn-s10:hover, .btn-s11:hover, .btn-s12:hover,
.btn-s13:hover, .btn-s14:hover  { filter: brightness(1.15); }

.btn-s1:active,  .btn-s2:active,  .btn-s3:active,  .btn-s4:active,
.btn-s5:active,  .btn-s6:active,  .btn-s7:active,  .btn-s8:active,
.btn-s9:active,  .btn-s10:active, .btn-s11:active, .btn-s12:active,
.btn-s13:active, .btn-s14:active  { filter: brightness(0.9); box-shadow: inset 0 2px 4px rgba(0,0,0,0.20); }


/* --- 6.6 Tag (outline chip) ---
 * Secondary, non-CTA label element. Pill-shaped, white/bg fill,
 * dark-swatch color for border and text.
 * Usage: <span class="tag tag-s11">Category</span>
 *        <button class="tag tag-s3">Filter</button>
 * ---------------------------------------------------------- */

.tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px;
  border-radius: 3px;
  border: 1px solid currentColor;
  background-color: var(--color-bg);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.5;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.12s;
  -webkit-appearance: none;
  appearance: none;
}

/* Swatch variants — dark text, light border */
.tag-s1  { color: var(--swatch-1-dark);  border-color: var(--swatch-1-light);  }
.tag-s2  { color: var(--swatch-2-dark);  border-color: var(--swatch-2-light);  }
.tag-s3  { color: var(--swatch-3-dark);  border-color: var(--swatch-3-light);  }
.tag-s4  { color: var(--swatch-4-dark);  border-color: var(--swatch-4-light);  }
.tag-s5  { color: var(--swatch-5-dark);  border-color: var(--swatch-5-light);  }
.tag-s6  { color: var(--swatch-6-dark);  border-color: var(--swatch-6-light);  }
.tag-s7  { color: var(--swatch-7-dark);  border-color: var(--swatch-7-light);  }
.tag-s8  { color: var(--swatch-8-dark);  border-color: var(--swatch-8-light);  }
.tag-s9  { color: var(--swatch-9-dark);  border-color: var(--swatch-9-light);  }
.tag-s10 { color: var(--swatch-10-dark); border-color: var(--swatch-10-light); }
.tag-s11 { color: var(--swatch-11-dark); border-color: var(--swatch-11-light); }
.tag-s12 { color: var(--swatch-12-dark); border-color: var(--swatch-12-light); }
.tag-s13 { color: var(--swatch-13-dark); border-color: var(--swatch-13-light); }
.tag-s14 { color: var(--swatch-14-dark); border-color: var(--swatch-14-light); }

/* Hover — light-swatch tint over bg (interactive tags only) */
.tag-s1:hover  { background-color: color-mix(in srgb, var(--swatch-1-light)  50%, var(--color-bg)); }
.tag-s2:hover  { background-color: color-mix(in srgb, var(--swatch-2-light)  50%, var(--color-bg)); }
.tag-s3:hover  { background-color: color-mix(in srgb, var(--swatch-3-light)  50%, var(--color-bg)); }
.tag-s4:hover  { background-color: color-mix(in srgb, var(--swatch-4-light)  50%, var(--color-bg)); }
.tag-s5:hover  { background-color: color-mix(in srgb, var(--swatch-5-light)  50%, var(--color-bg)); }
.tag-s6:hover  { background-color: color-mix(in srgb, var(--swatch-6-light)  50%, var(--color-bg)); }
.tag-s7:hover  { background-color: color-mix(in srgb, var(--swatch-7-light)  50%, var(--color-bg)); }
.tag-s8:hover  { background-color: color-mix(in srgb, var(--swatch-8-light)  50%, var(--color-bg)); }
.tag-s9:hover  { background-color: color-mix(in srgb, var(--swatch-9-light)  50%, var(--color-bg)); }
.tag-s10:hover { background-color: color-mix(in srgb, var(--swatch-10-light) 50%, var(--color-bg)); }
.tag-s11:hover { background-color: color-mix(in srgb, var(--swatch-11-light) 50%, var(--color-bg)); }
.tag-s12:hover { background-color: color-mix(in srgb, var(--swatch-12-light) 50%, var(--color-bg)); }
.tag-s13:hover { background-color: color-mix(in srgb, var(--swatch-13-light) 50%, var(--color-bg)); }
.tag-s14:hover { background-color: color-mix(in srgb, var(--swatch-14-light) 50%, var(--color-bg)); }

.tag:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }


/* --- 6.7 Toggle (switch-style checkbox) ---
 * SwiftUI: Toggle("Label", isOn: $isOn)
 *   .toggleStyle(.switch)
 * States: on, off, disabled
 * ---------------------------------------------------------- */

.toggle {
  -webkit-appearance: none;
  appearance: none;
  width: 44px;
  height: 24px;
  border-radius: 12px;
  background-color: var(--gray-300);
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
  transition: background-color 0.2s;
  vertical-align: middle;
}

.toggle::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.20);
  transition: transform 0.2s;
}

.toggle:checked              { background-color: var(--swatch-11-light); }
.toggle:checked::after       { transform: translateX(20px); }
.toggle:focus-visible        { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.toggle:disabled             { opacity: 0.45; cursor: not-allowed; }

.toggle-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
}
.toggle-label:has(.toggle:disabled) { cursor: not-allowed; color: var(--color-text-disabled); }


/* --- 6.7 Radio Button ---
 * SwiftUI: Picker("Label", selection: $value) { ... }
 *   .pickerStyle(.radioGroup)  [macOS]
 * States: selected, unselected, disabled
 * ---------------------------------------------------------- */

.radio {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid var(--color-border-input);
  background-color: var(--color-panel);
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
  transition: border-color 0.15s;
  vertical-align: middle;
}

.radio:checked {
  border-color: var(--swatch-11-light);
  border-width: 2px;
}

.radio:checked::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: var(--swatch-11-light);
}

.radio:focus-visible  { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.radio:disabled       { opacity: 0.45; cursor: not-allowed; }

.radio-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
}
.radio-label:has(.radio:disabled) { cursor: not-allowed; color: var(--color-text-disabled); }


/* --- 6.8 Checkbox ---
 * SwiftUI: Toggle("Label", isOn: $isOn)
 * States: unchecked, hover, checked, disabled
 * Accent color controlled by --color-checked / --color-checked-border.
 * Swap to any swatch pair to re-theme per form.
 * ---------------------------------------------------------- */

.checkbox {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 4.5px;
  border: 1.5px solid var(--gray-400);
  background-color: var(--gray-300);
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
  transition: background-color 0.15s, border-color 0.15s;
  vertical-align: middle;
}

.checkbox:hover {
  background-color: color-mix(in srgb, var(--color-checked) 50%, transparent);
  border-color: var(--color-checked-border);
}

.checkbox:checked {
  background-color: var(--color-checked);
  border-color: var(--color-checked-border);
}

.checkbox:checked::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 6px;
  width: 5px;
  height: 9px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(45deg);
}

.checkbox:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.checkbox:disabled       { opacity: 0.45; cursor: not-allowed; }

.checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
}
.checkbox-label:has(.checkbox:disabled) { cursor: not-allowed; color: var(--color-text-disabled); }


/* --- 6.9 Toast Alert (ephemeral, dismissible) ---
 * SwiftUI: No direct equivalent — use custom overlay / .alert()
 * Positioned fixed bottom-right. Show/hide via JS class .toast-visible.
 * ---------------------------------------------------------- */

.toast {
  position: fixed;
  bottom: var(--space-5);
  right: var(--space-5);
  max-width: 320px;
  width: calc(100vw - var(--space-5) * 2);
  background-color: var(--color-panel);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-3) var(--space-4);
  box-shadow: 0 4px 16px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.08);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  z-index: 1000;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.2s, transform 0.2s;
}

.toast.toast-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.toast-body  { flex: 1; font-size: var(--text-sm); line-height: var(--leading-normal); }
.toast-title { font-weight: 600; margin-bottom: 2px; }
.toast-msg   { color: var(--color-text-secondary); }

.toast-dismiss {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-secondary);
  font-size: 1.1rem;
  line-height: 1;
  padding: var(--space-1) var(--space-2);
  flex-shrink: 0;
  min-width: 32px;
  min-height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  margin-top: -2px;
  margin-right: -4px;
}
.toast-dismiss:hover        { color: var(--color-text); background-color: var(--gray-100); }
.toast-dismiss:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }


/* --- 6.10 Persistent Alert (inline / banner) ---
 * SwiftUI: custom HStack with colored leading bar + Text
 * 4 semantic variants: info, success, warning, error
 * ---------------------------------------------------------- */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: 4px;
  border-left: 4px solid currentColor;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.alert-title { font-weight: 600; margin-bottom: 2px; }

.alert-info    { color: var(--swatch-11-dark); background-color: var(--alert-info-bg); }
.alert-success { color: var(--swatch-8-dark);  background-color: var(--alert-success-bg); }
.alert-warning { color: var(--swatch-5-dark);  background-color: var(--alert-warning-bg); }
.alert-error   { color: var(--swatch-1-dark);  background-color: var(--alert-error-bg); }

[data-theme="dark"] .alert-info    { color: var(--swatch-11-light); }
[data-theme="dark"] .alert-success { color: var(--swatch-8-light); }
[data-theme="dark"] .alert-warning { color: var(--swatch-5-light); }
[data-theme="dark"] .alert-error   { color: var(--swatch-1-light); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) .alert-info    { color: var(--swatch-11-light); }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .alert-success { color: var(--swatch-8-light); }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .alert-warning { color: var(--swatch-5-light); }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .alert-error   { color: var(--swatch-1-light); }
}


/* --- 6.11 Image + Caption ---
 * SwiftUI: VStack(alignment: .leading, spacing: 4) { Image(...); Text(caption).font(.caption) }
 * ---------------------------------------------------------- */

.img-block { display: block; }
.img-block img { width: 100%; border-radius: 4px; display: block; }

.img-caption {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
  line-height: var(--leading-normal);
}

/* CSS-only image placeholder (no external URL needed) */
.img-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--gray-100);
  color: var(--gray-400);
  border-radius: 4px;
  font-size: var(--text-xs);
  font-family: var(--font-mono);
  aspect-ratio: 16 / 9;
  width: 100%;
}


/* ============================================================
   7. GRID UTILITIES
   ============================================================
   SwiftUI: LazyVGrid(columns: [...], spacing: 16)
   Responsive: collapses to 1 column on small screens.
   ============================================================ */

.grid {
  display: grid;
  gap: var(--space-4);
}

.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

/* Tablet: 3/4-col grids become 2-col */
@media (max-width: 900px) {
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

/* Mobile: all grids become 1-col */
@media (max-width: 600px) {
  .grid-2,
  .grid-3,
  .grid-4 { grid-template-columns: 1fr; }

  /* Stack post/project list items vertically on mobile */
  .post-list-item,
  .project-list-item {
    flex-direction: column;
  }

  .post-list-item .post-thumbnail,
  .project-list-item .post-thumbnail {
    max-width: 100%;
    max-height: none;
    width: 100%;
  }

  .post-list-item .post-thumbnail img,
  .project-list-item .post-thumbnail img {
    width: 100%;
    height: auto;
  }
}


/* ============================================================
   8. LAYOUT PATTERNS
   ============================================================ */


/* --- 8.1 Menu (navigation link list) ---
 * SwiftUI: List { NavigationLink(label, destination) }
 *   or VStack with custom row views
 * ---------------------------------------------------------- */

.menu {
  list-style: none;
  padding: 0;
  margin: 0;
}

.menu-item a {
  display: block;
  padding: var(--space-2) var(--space-3);
  color: var(--color-text);
  text-decoration: none;
  border-radius: 4px;
  font-size: var(--text-base);
  transition: background-color 0.15s, color 0.15s;
}

.menu-item a:hover          { background-color: var(--gray-100); text-decoration: none; }
.menu-item a.active         { background-color: var(--swatch-11-dark); color: #F7F7F5; }
.menu-item a.active:hover   { background-color: var(--swatch-11-dark); filter: brightness(1.15); }
.menu-item a:focus-visible  { outline: 2px solid var(--color-focus); outline-offset: 2px; }

.menu-divider {
  height: 1px;
  background-color: var(--color-border);
  margin: var(--space-1) 0;
}

.menu-section-label {
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}


/* --- 8.2 Blog Post List ---
 * SwiftUI: List(posts) { PostRowView(post: $0) }
 * ---------------------------------------------------------- */

.post-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.post-list-item {
  display: flex;
  align-items: stretch;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
  position: relative;
}

.post-list-item:last-child { border-bottom: none; }

.post-list-item .post-content {
  flex: 1;
  min-width: 0;
}

.post-thumbnail {
  flex-shrink: 0;
  align-self: stretch;
  min-height: 0;
  max-height: 200px;
  max-width: 200px;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  justify-content: center;
}

.post-thumbnail img {
  height: 100%;
  width: auto;
  max-width: none;
  display: block;
}

.post-date {
  grid-column: 1;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-1);
  font-variant-numeric: tabular-nums;
}

.post-title {
  grid-column: 1;
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-2);
  line-height: var(--leading-tight);
  overflow-wrap: break-word;
}

.post-title a { color: inherit; }
.post-title a:hover { color: var(--color-link-accent); text-decoration: none; }

/* Expand-link: makes the whole item clickable via the title anchor.
 * Interactive children (.post-tags, .post-readmore) need z-index: 1. */
.post-title a::after {
  content: '';
  position: absolute;
  inset: 0;
}

.post-excerpt {
  grid-column: 1;
  font-size: var(--text-base);
  color: var(--color-text-secondary);
  line-height: var(--leading-relaxed);
  margin-bottom: var(--space-2);
}

.post-readmore {
  grid-column: 1;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-link-accent);
  position: relative;
  z-index: 1;
}

.post-readmore:hover { text-decoration: underline; }

.post-tags {
  grid-column: 1;
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: var(--space-2);
  position: relative;
  z-index: 1;
}

.post-tag {
  padding: 2px var(--space-2);
  background-color: var(--gray-100);
  border-radius: 4px;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}

a.post-tag {
  color: inherit;
  text-decoration: none;
}

a.post-tag:hover {
  background-color: var(--gray-200);
  color: var(--color-text);
}


/* --- 8.2b Project List ---
 * Variant of post-list-item for portfolio/project entries.
 * Wider thumbnail column, more vertical padding, year-based date label.
 * Shares all .post-* child element styles with the blog post list.
 * ---------------------------------------------------------- */

.project-list-item {
  display: flex;
  gap: var(--space-5);
  padding: var(--space-7) 0;
  border-bottom: 1px solid var(--color-border);
  position: relative;
}

.project-list-item:last-child { border-bottom: none; }

.project-list-item .post-content {
  flex: 1;
  min-width: 0;
}

.project-list-item .post-thumbnail {
  max-height: 280px;
  max-width: 280px;
  border-radius: 6px;
}

.project-list-item .post-thumbnail img {
  height: 100%;
  width: auto;
}

.project-list-item .post-date {
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--color-link-accent);
  margin-bottom: var(--space-2);
}

.project-list-item .post-title {
  font-size: var(--text-3xl);
  font-weight: 700;
  margin-bottom: var(--space-3);
  line-height: var(--leading-tight);
}

.project-list-item .post-excerpt {
  font-size: var(--text-lg);
  margin-bottom: var(--space-3);
}

.project-list-item .post-tags {
  margin-top: var(--space-3);
}


/* --- 8.3 Image Grid ---
 * SwiftUI: LazyVGrid(columns: [.adaptive(minimum: 160)])
 * Uses .grid-3 utility. Each cell is .img-block.
 * ---------------------------------------------------------- */

/* .image-grid uses .grid utility classes — no additional rules needed */


/* --- 8.4 Blog Post (single article) ---
 * SwiftUI: ScrollView { VStack(alignment: .leading) { ... } }
 *   with .frame(maxWidth: 680)
 * ---------------------------------------------------------- */

.prose {
  max-width: var(--prose-width, 680px);
  margin: 0 auto;
}

.prose-header { margin-bottom: var(--space-6); }
.prose-header .post-date { font-size: var(--text-sm); }
.prose-header h1 { margin-top: var(--space-2); margin-bottom: var(--space-3); }
.prose-header .post-excerpt { font-size: var(--text-lg); }

.prose-body a       { color: var(--color-link); }
.prose-body p       { margin-top: var(--space-4); margin-bottom: var(--space-4); }
.prose-body h2      { margin-top: var(--space-7); margin-bottom: var(--space-3); }
.prose-body h3      { margin-top: var(--space-6); margin-bottom: var(--space-2); }
.prose-body ul,
.prose-body ol      { padding-left: var(--space-5); margin-bottom: var(--space-4); }
.prose-body li      { margin-bottom: var(--space-1); line-height: var(--leading-relaxed); }
.prose-body code    { background: var(--gray-100); padding: 1px 5px; border-radius: 3px; }
.prose-body pre     { background: var(--gray-100); padding: var(--space-4); border-radius: 4px; overflow-x: auto; margin-bottom: var(--space-4); }
.prose-body pre code{ background: none; padding: 0; }
.prose-body blockquote {
  border-left: 3px solid var(--color-border-input);
  padding-left: var(--space-4);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-4);
  font-style: italic;
}

.prose-footer { margin-top: var(--space-7); padding-top: var(--space-5); border-top: 1px solid var(--color-border); }


/* --- 8.5 Project Post ---
 * SwiftUI: ScrollView { VStack { header-grid; body } }
 * Wider than prose — hero image + meta side by side on desktop.
 * ---------------------------------------------------------- */

.project-header {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  margin-bottom: var(--space-6);
}

@media (min-width: 640px) {
  .project-header { grid-template-columns: 2fr 1fr; }
}

.project-hero { width: 100%; }
.project-meta { display: flex; flex-direction: column; gap: var(--space-3); }
.project-meta h1 { font-size: var(--text-3xl); }

.project-tech-stack {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.project-tech-tag {
  padding: var(--space-1) var(--space-3);
  background-color: var(--swatch-11-light);
  color: var(--swatch-11-dark);
  border-radius: 4px;
  font-size: var(--text-xs);
  font-weight: 500;
}

.project-body { max-width: 800px; }
.project-body p { margin-bottom: var(--space-4); line-height: var(--leading-relaxed); }


/* ============================================================
   9. SITE LAYOUT (feesta.com CMS)
   ============================================================ */


/* --- 9.1 Page layout container --- */

.page-layout {
  width: 80vw;
  max-width: 700px;
  margin-left: 5vw;
}

@media (max-width: 480px) {
  .page-layout { width: 100%; margin-left: 0; padding-left: 5px; padding-right: 5px; }
}

@media (min-width: 480px) {
  .page-layout { width: 80vw; margin-left: 5vw; }
  li { max-width: 700px; }
}


/* --- 9.2 Site header --- */

.site-header { margin-bottom: var(--space-5); }

.site-title {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 4rem;
  color: var(--gray-100);
  display: block;
  margin-top: 1em;
  text-decoration: none;
}
.site-title:hover { color: var(--gray-200); text-decoration: none; }

@media (max-width: 480px) {
  .site-title { font-size: 2.5rem; }
}

[data-theme="dark"] .site-title       { color: var(--swatch-7-light); }
[data-theme="dark"] .site-title:hover { color: var(--swatch-6-light); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) .site-title       { color: var(--swatch-7-light); }
  :root:not([data-theme="light"]):not([data-theme="dark"]) .site-title:hover { color: var(--swatch-6-light); }
}

.site-subtitle {
  font-size: var(--text-lg);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-2);
  line-height: var(--leading-relaxed);
}

.site-subtitle-secondary {
  font-size: var(--text-base);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-2);
}


/* --- 9.3 Squiggly HR --- */
/* Removed */



/* --- 9.4 Nav text links (back/home) --- */

.nav-text-link {
  display: inline-block;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-text);
  font-size: var(--text-base);
  font-weight: 500;
  padding: 0;
  margin: 0;
  background: none;
  border: none;
  font-family: var(--font-sans);
  cursor: pointer;
  padding-bottom: var(--space-5);
}
.nav-text-link { transition: opacity 0.15s; }
.nav-text-link:hover        { opacity: 0.7; text-decoration: none; }
.nav-text-link:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; opacity: 1; }


/* --- 9.5 Card (thumbnail item) --- */

.card {
  display: block;
  color: var(--color-text-secondary);
  text-transform: uppercase;
  text-decoration: none;
  font-size: var(--text-xs);
}
.card { transition: opacity 0.15s; }
.card:hover { opacity: 0.7; text-decoration: none; }

.card-thumbnail {
  height: 180px;
  width: 100%;
  object-fit: cover;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  display: block;
}

.card-title {
  margin: var(--space-1) 0 0 0;
  padding: 0;
  font-size: var(--text-sm);
  font-weight: 700;
  overflow-wrap: break-word;
  /* color set by JS from image palette — no override */
}


/* --- 9.6 Archive (projects/tagged listing) --- */

.archive-heading {
  color: var(--color-text-secondary);
  font-size: var(--text-xl);
  font-weight: 400;
  text-transform: uppercase;
  text-decoration: none;
  padding-bottom: var(--space-3);
}


/* --- 9.7 Page content (markdown pages) --- */

.page-content h1 { font-weight: 600; font-size: var(--text-lg); }
.page-content h2 { font-weight: 300; }
.page-content h3 { font-weight: 600; font-size: var(--text-sm); }
.page-content a {
  text-decoration: none;
  color: var(--color-link-accent);
  display: inline-block;
  font-weight: 600;
}
.page-content a.date {
  font-weight: 400;
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
}
.page-content a.date:hover { color: var(--color-text-secondary); text-decoration: none; }


/* --- 9.8 Block code (pre > code) --- */

.prose-body pre > code {
  display: block;
  margin-left: 5%;
  max-width: 90%;
  border-left: 1px dashed var(--color-border-input);
  padding-left: 1em;
  color: var(--color-code);
  white-space: pre;
  overflow-wrap: anywhere;
  word-break: break-word;
  overflow-x: auto;
  background: none;
  font-size: var(--text-sm);
}


/* --- 9.9 Responsive image utilities --- */

img.small  { max-width: 200px; }
img.medium { max-width: 400px; display: block; margin: 0 auto; }

@media (max-width: 480px) {
  img.small  { max-width: 30%; }
  img.medium { max-width: 40%; }
}


/* ============================================================
   10. ACCESSIBILITY UTILITIES
   ============================================================ */

/* Respect user's motion preference — disable non-essential transitions */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* ============================================================
   11. MOBILE / TOUCH ADAPTATIONS
   ============================================================
   All interactive elements meet WCAG 2.5.5 minimum 44×44px
   touch target on narrow viewports.
   iOS auto-zoom prevention: all inputs use font-size ≥ 16px
   (var(--text-base) = 1rem = 16px — already satisfied).
   ============================================================ */

@media (max-width: 768px) {

  /* Form controls — 44px minimum tap height */
  .input,
  .select {
    min-height: 44px;
  }

  /* Buttons — 44px minimum tap height */
  .btn {
    min-height: 44px;
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
  }

  /* Menu items — 44px minimum tap height, flex for vertical centering */
  .menu-item a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }

  /* Toggle / radio / checkbox labels — full-height tap area */
  .toggle-label,
  .radio-label,
  .checkbox-label {
    min-height: 44px;
  }

  /* Toast dismiss — 44px tap area */
  .toast-dismiss {
    min-width: 44px;
    min-height: 44px;
  }

  /* Prose: tighter heading sizes for narrow viewports */
  .prose h1 { font-size: var(--text-2xl); }
  .prose h2 { font-size: var(--text-xl); }

  /* In-content link tap area expansion */
  .post-readmore {
    display: inline-block;
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
  }

  /* Nav text link: add top padding so total tap height ≥ 44px
     (existing padding-bottom: var(--space-5) = 24px + 16px line + 4px top = 44px) */
  .nav-text-link {
    padding-top: var(--space-1);
  }

}


/* ============================================================
   12. VISUAL TEXTURE
   ============================================================
   Subtle film-grain overlay — adds tactile warmth, breaks the
   flatness of pure CSS without introducing decorative noise.
   Visible as a light paper texture; recedes in dark mode.
   ============================================================ */

body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 2147483646;
  pointer-events: none;
  background-size: 256px 256px;
  opacity: 0.05;
  mix-blend-mode: soft-light;
}


/* --- Menu section labels: instrument-panel readout style ---
 * Already uppercase + tracked; mono makes the taxonomy explicit.
 * ---------------------------------------------------------- */
.menu-section-label { font-family: var(--font-mono); }


/* --- Post tags: data-label aesthetic, not friendly pills ---
 * Monospace tags feel like metadata fields, not decorations.
 * ---------------------------------------------------------- */
.post-tag { font-family: var(--font-mono); }
