/* Modagenic design tokens — the Hairline system of cs-predictive (DESIGN.md › Tokens), same names, same values.
   White, Geist, 1 px hairlines, small calm titles; black only for the primary button, focus and selection;
   colour only for meaning. Posts in the feed have no shadow: hairlines only. Components use these; no raw sizes, colours or durations anywhere else. docs/design.md. */

/* Geist Sans + Geist Mono (OFL, /fonts/GEIST-OFL.txt) */
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/geist-400.woff2) format('woff2'); }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/geist-500.woff2) format('woff2'); }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/geist-mono-400.woff2) format('woff2'); }

:root {
  color-scheme: light; /* dark: the block at the end (data-theme / system) */

  /* ---------- type: Geist for everything, Geist Mono for numbers (distance, rating, counts, cost) ---------- */
  --sans: 'Geist', ui-sans-serif, system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --t-12: 12px;  /* meta, distance, pills, counts, hints */
  --t-13: 13px;  /* labels, chips, sm buttons, segmented control */
  --t-14: 14px;  /* body, inputs, buttons, vendor name */
  --t-15: 15px;  /* wordmark, empty-state title */
  --t-16: 16px;  /* vendor name in the detail, section / sheet titles, the travel cost; inputs on phones */
  --t-20: 20px;  /* the vendor name in the detail — the largest heading in the app */
  --lh-text: 1.5; --lh-title: 1.3;
  --w-regular: 400; --w-medium: 500; /* emphasis is 500, never bolder */
  --ls-wordmark: .02em; --ls-title: -.01em; --ls-page: -.02em;

  /* ---------- spacing: 4 px grid ---------- */
  --s-0h: 2px; --s-1: 4px; --s-1h: 6px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px; --s-12: 48px; --s-16: 64px;

  /* ---------- sizes ---------- */
  --h-xs: 24px; --h-sm: 32px; --h-md: 36px; --h-lg: 40px; --h-xl: 48px; /* controls: sm 32 · md 36 · lg 40 */
  --h-input: var(--h-md); --t-input: var(--t-14);                      /* text fields 36 (40 + 16 px text on phones: no iOS zoom) */
  --h-pill: 20px; --h-count: 18px;
  --h-row: 44px; --h-dlg-head: 52px; --h-tab: 44px; --bar-h: 52px;
  --ic-xs: 12px; --ic-sm: 14px; --ic: 16px; --ic-md: 20px; --ic-lg: 24px; --ic-stroke: 1.75;

  /* ---------- shape ---------- */
  --r-sm: 6px;      /* pills, tags, counts */
  --r: 8px;         /* controls: buttons, inputs, chips, icon buttons, segmented control */
  --r-card: 12px;   /* cards, panels, sheets, toasts */
  --r-pill: 999px;  /* the search pill, the sheet grip and the Peta / Daftar buttons; dots and markers use 50 % */
  --bw: 1px;

  /* ---------- elevation: faint card shadow, one float shadow, one dim, one blur ---------- */
  --shadow-xs: 0 1px 2px rgb(0 0 0 / .03);  /* the tiny lift under controls */
  --shadow-card: 0 1px 2px rgb(0 0 0 / .04), 0 2px 8px rgb(0 0 0 / .025); /* cards (with a hairline) */
  --shadow-pop: 0 12px 32px -12px rgb(0 0 0 / .14), 0 0 0 1px rgb(0 0 0 / .04); /* detail panel, sheet, floating buttons, toast — never on posts */
  --scrim: rgb(10 10 10 / .24);           /* behind the phone bottom sheet */
  --blur: 4px;
  --blur-float: 16px;
  --surface-float: rgb(255 255 255 / .92); /* floating controls over the map */

  /* ---------- stacking ---------- */
  --z-sticky: 10; --z-map-ui: 500; --z-panel: 1000; --z-scrim: 1100; --z-sheet: 1200; --z-toast: 1300; /* Leaflet panes sit at 400–700 */

  /* ---------- motion: three durations, one easing ---------- */
  --dur-1: 120ms;  /* hover, press */
  --dur-2: 200ms;  /* toast, side panel fade */
  --dur-3: 280ms;  /* sheets that slide */
  --ease: cubic-bezier(.2, .8, .2, 1);
  --dur-spin: 700ms;     /* busy spinner turn */
  --dur-shimmer: 1.4s;   /* skeleton pulse */

  /* ---------- colour: white, black ink, neutral greys; colour only for meaning ---------- */
  --bg: #ffffff;
  --surface: #ffffff;
  --raised: #ffffff;          /* side panel, sheet, toast — the third depth level (shows in dark) */
  --subtle: #fafafa;          /* hover of quiet rows, segmented track, map background */
  --skeleton: #f3f3f3;
  --hover: rgb(0 0 0 / .04);
  --hover-solid: #f5f5f5;     /* hover / selected row, tags */
  --border: #ebebeb;          /* hairlines: cards, dividers, rows */
  --border-strong: #e5e5e5;   /* control borders */
  --border-hover: #d4d4d4;    /* control border on hover */
  --ink: #0a0a0a;
  --ink-2: #404040;
  --muted: #737373;           /* meta text (4.7:1) */
  --faint: #a3a3a3;           /* icons at rest, placeholders, separators — never text (2.5:1) */
  --grey: #e5e5e5;            /* selection */
  --primary: #0a0a0a;
  --primary-ink: #ffffff;
  --primary-hover: #262626;
  --on-color: #ffffff;
  --link: var(--ink);
  --ring-selected: var(--ink);
  --focus: var(--ink); --ring-w: 2px; /* :focus-visible ring */
  --o-disabled: .5; --o-busy: .5; /* disabled controls · results kept visible while refining */
  /* meaning only: ok (open / verified), warn (approximate location), bad (error), info (neutral) */
  --ok: #15803d; --ok-bg: #f0fdf4; --ok-bd: #dcfce7;
  --bad: #dc2626; --bad-bg: #fef2f2; --bad-bd: #fee2e2; --bad-ink: #b91c1c; /* --bad-ink: error text on --bad-bg (5.9:1); --bad = icons, borders */
  --warn: #b45309; --warn-bg: #fffbeb; --warn-bd: #fef3c7;
  --info: #404040; --info-bg: #fafafa; --info-bd: #ebebeb;

  /* ---------- map (Leaflet) ---------- */
  --mk: 10px;            /* vendor dot */
  --mk-sel: 16px;        /* selected vendor dot */
  --mk-hit: 24px;        /* marker hit box (iconSize in JS); 44 on touch screens */
  --mk-approx: 14px;     /* approximate-location ring (hollow, so a little larger than a dot) */
  --mk-ring: 2px;        /* white ring around a dot */
  --mk-fill: var(--ink);
  --mk-halo: var(--surface);
  --loc: var(--ok); --loc-halo: rgb(21 128 61 / .16); /* the reference point (titik acuan): an --ok ring + soft halo */
  --mk-me: 12px;         /* reference-point ring */
  --route: var(--ink); --route-w: 4px; --route-w-est: 2px; /* road route · straight-line estimate (dashed) */
  --map-filter: grayscale(1) contrast(.55) brightness(1.3); /* tiles in calm, low-contrast greys (OSM standard tiles are colourful and their black POI symbols must not read as vendor dots) */

  /* ---------- layout ---------- */
  --w-feed: 540px;       /* the one centred feed column (all widths); keeps a desktop Instagram embed under ~500 px tall */
  --w-detail: 600px;     /* detail panel from 640 px (its posts grid is larger than the feed's); full screen below */
  --w-mini: 168px;       /* "Vendor serupa" mini card */
  --ig-head-s: 147px;    /* Instagram profile-embed header cropped off above the posts (frame ≤ 480 px wide; post.js) */
  --ig-head-l: 158px;    /* … frame wider than 480 px */
  --gutter: var(--s-4);  /* side gutter of the feed, the detail and the sheets */
  --w-toast: 420px;
  --w-dlg: 440px;        /* Cari vendor / Lokasi / Laporkan dialog from 640 px */
  --h-menu: 320px;       /* suggestions menu max height */
  --touch: 44px;         /* minimum touch area on phones (ux.md 7) */
  --h-mini-map: 160px;   /* the mini map in the detail */
}

/* ---------- dark (cs-predictive palette "Netral"): <html data-theme="dark">, or no attribute + a dark system ---------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0a0a0a; --surface: #111111; --raised: #1a1a1a; --subtle: #161616; --skeleton: #1f1f1f;
    --hover: rgb(255 255 255 / .05); --hover-solid: #1f1f1f;
    --border: #262626; --border-strong: #2e2e2e; --border-hover: #3d3d3d;
    --ink: #ededed; --ink-2: #c9c9c9; --muted: #a1a1a1; --faint: #6b6b6b; --grey: #2e2e2e;
    --primary: #ededed; --primary-ink: #0a0a0a; --primary-hover: #ffffff; --ring-selected: #8f8f8f;
    --ok: #4ade80; --ok-bg: rgb(74 222 128 / .1); --ok-bd: rgb(74 222 128 / .2);
    --bad: #f87171; --bad-bg: rgb(248 113 113 / .1); --bad-bd: rgb(248 113 113 / .2); --bad-ink: #f87171;
    --warn: #f2b84b; --warn-bg: rgb(242 184 75 / .1); --warn-bd: rgb(242 184 75 / .2);
    --info: #c9c9c9; --info-bg: #161616; --info-bd: #262626;
    --shadow-xs: 0 1px 2px rgb(0 0 0 / .3);
    --shadow-card: 0 0 0 1px rgb(255 255 255 / .02), 0 8px 24px rgb(0 0 0 / .4);
    --shadow-pop: 0 0 0 1px rgb(255 255 255 / .06), 0 16px 40px -12px rgb(0 0 0 / .6);
    --scrim: rgb(0 0 0 / .55);
    --surface-float: rgb(26 26 26 / .92);
    --loc-halo: rgb(74 222 128 / .2);
    --map-filter: grayscale(1) invert(1) brightness(.85) contrast(.9);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0a0a0a; --surface: #111111; --raised: #1a1a1a; --subtle: #161616; --skeleton: #1f1f1f;
  --hover: rgb(255 255 255 / .05); --hover-solid: #1f1f1f;
  --border: #262626; --border-strong: #2e2e2e; --border-hover: #3d3d3d;
  --ink: #ededed; --ink-2: #c9c9c9; --muted: #a1a1a1; --faint: #6b6b6b; --grey: #2e2e2e;
  --primary: #ededed; --primary-ink: #0a0a0a; --primary-hover: #ffffff; --ring-selected: #8f8f8f;
  --ok: #4ade80; --ok-bg: rgb(74 222 128 / .1); --ok-bd: rgb(74 222 128 / .2);
  --bad: #f87171; --bad-bg: rgb(248 113 113 / .1); --bad-bd: rgb(248 113 113 / .2); --bad-ink: #f87171;
  --warn: #f2b84b; --warn-bg: rgb(242 184 75 / .1); --warn-bd: rgb(242 184 75 / .2);
  --info: #c9c9c9; --info-bg: #161616; --info-bd: #262626;
  --shadow-xs: 0 1px 2px rgb(0 0 0 / .3);
  --shadow-card: 0 0 0 1px rgb(255 255 255 / .02), 0 8px 24px rgb(0 0 0 / .4);
  --shadow-pop: 0 0 0 1px rgb(255 255 255 / .06), 0 16px 40px -12px rgb(0 0 0 / .6);
  --scrim: rgb(0 0 0 / .55);
  --surface-float: rgb(26 26 26 / .92);
  --loc-halo: rgb(74 222 128 / .2);
  --map-filter: grayscale(1) invert(1) brightness(.85) contrast(.9);
}
:root[data-theme="light"] { color-scheme: light; }

@media (max-width: 760px) {
  /* touch: text fields 40 high with 16 px text (no iOS zoom on focus) */
  :root { --h-input: var(--h-lg); --t-input: var(--t-16); }
}
@media (pointer: coarse) {
  :root { --mk-hit: var(--touch); } /* map.js uses the same 44 px iconSize */
}
@media (prefers-reduced-motion: reduce) {
  :root { --dur-1: 0ms; --dur-2: 0ms; --dur-3: 0ms; }
}
