
/* Hallmark · genre: warm-utilitarian · macrostructure: shared task card · design-system: design.md · designed-as-app
 * pre-emit critique: P5 H5 E5 S5 R5 V4 · contrast: pass (40–41) · mobile: pass (34,49–57)
 */
/**
 * Metric-matched fallback faces for Mitr/Sarabun (Lighthouse CLS pass,
 * 2026-09-09; revised same day — an earlier cut used font-display:optional
 * instead, which was rejected: Mitr/Sarabun are the brand faces (design.md
 * § 3) and optional means a reader who misses the ~100ms block window on a
 * slow connection never gets them, for the rest of that page view). Google
 * Fonts still ships display:swap (views.ts GOOGLE_FONTS_URL) — swap always
 * shows the real face once it arrives — but swap repaints whatever the
 * fallback already laid out, and a generic fallback's box (line height,
 * average character width) differs from Mitr/Sarabun's enough to reflow
 * the page. These two @font-face rules give the *fallback* Mitr/Sarabun's
 * own box, via the four CSS Fonts Module 4 metric overrides, so the swap
 * repaints glyphs without moving anything around them.
 *
 * Numbers were computed the capsize/fontaine way, with fontkit: for the
 * real webfont file and the local fallback, read unitsPerEm/ascent/descent/
 * lineGap, and average the advance width over the 46 Thai consonants
 * (ก–ฮ, U+0E01–U+0E2E) rather than every glyph in the file — a fallback
 * with a large multi-script glyph repertoire (a macOS system font commonly
 * covers dozens of scripts in one file) skews a whole-file average far past
 * anything a Thai reader's line of text looks like; a first pass that
 * averaged every glyph produced a 280%+ ascent-override, which is what
 * happens when the two files are not actually being compared on the same
 * text. Then, per character width normalised to each font's own em (raw
 * advance widths are not comparable across files with a different
 * unitsPerEm — Thonburi's is 2560, Mitr/Sarabun's is 1000):
 *   webEm      = webfont.avgWidth  / webfont.unitsPerEm
 *   fallbackEm = fallback.avgWidth / fallback.unitsPerEm
 *   size-adjust        = webEm / fallbackEm
 *   ascent-override     = (webfont.ascent  / webfont.unitsPerEm) / size-adjust
 *   descent-override    = (webfont.descent / webfont.unitsPerEm) / size-adjust
 *   line-gap-override   = (webfont.lineGap / webfont.unitsPerEm) / size-adjust
 * measured against the Thai-subset files this page actually loads (Mitr
 * weight 700 — every heading and the wordmark; Sarabun weight 400 — body
 * text) and, as the local-font reference, macOS's bundled Thonburi
 * (Regular for the Sarabun pairing, Bold for Mitr's) — the one local()
 * candidate below this repo could actually fetch, load and measure, and
 * then verify end-to-end with a real headless-Chrome Lighthouse run on this
 * machine (CLS on /หางาน dropped from a reproducible ~0.17 with the
 * whole-glyph-average numbers to 0 across five runs with these). "Noto Sans
 * Thai" and "Leelawadee UI" go first in the local() list because they are
 * the more likely match on Android/ChromeOS and Windows respectively, but
 * their own metrics were not available to measure in this environment —
 * Thonburi's numbers are the closest verified proxy for them, not a
 * verification that they are exactly right too. Re-run apps/api's font
 * metrics script (see the PR that added this comment) if Mitr or Sarabun's
 * published files ever change, or when a Windows/Android box is available
 * to measure Leelawadee UI/Noto Sans Thai directly instead of assuming.
 */
@font-face{
  font-family:"Mitr Fallback";
  src:local("Noto Sans Thai"),local("Leelawadee UI"),local("Thonburi"),local("Noto Sans");
  font-weight:700;
  ascent-override:109.82%;
  descent-override:40.11%;
  line-gap-override:0%;
  size-adjust:104.72%;
}
@font-face{
  font-family:"Sarabun Fallback";
  src:local("Noto Sans Thai"),local("Leelawadee UI"),local("Thonburi"),local("Noto Sans");
  font-weight:400;
  ascent-override:107.24%;
  descent-override:23.30%;
  line-gap-override:0%;
  size-adjust:99.59%;
}
:root{
  --color-paper:#FBF6EC;
  --color-paper-2:#F3EBDB;
  --color-paper-3:#E8DECB;
  --color-card:#FFFDF7;
  --color-ink:#1E1A16;
  --color-ink-2:#4A413A;
  --color-muted:#6B6055;
  --color-rule:#D9CDB8;
  --color-rule-2:#E6DCCB;
  /* 2026-09-06 (Astra proposal, founder-approved) — the SSR page had its own
     hand-written tomato (#B4452C and a lighter hover/deep pair), so the public
     /j/:id primary was a different colour from the SPA and the app. These are
     design.md § 2's generated values for oklch(50% .15 33) and its states;
     regenerate them with 'bun run design:tokens', never by eye. */
  --color-primary:#A73923;
  --color-primary-ink:#FCF5E7;
  --color-primary-hover:#9A2B16;
  --color-primary-deep:#892312;
  --color-primary-tint:#FEE0D8;
  --color-accent:#D9603F;
  --color-accent-tint:#F3EBDB;
  --color-tag-ink:#1E1A16;
  --color-focus:#2F5FD6;
  --status-pending:#4F5661;
  --status-pending-bg:#E7EAED;
  --status-contacted:#005187;
  --status-contacted-bg:#D8EDFC;
  --status-hired:#005725;
  --status-hired-bg:#D7F4DC;
  --status-completed:#01421A;
  --status-completed-bg:#D7F4DC;
  --status-rejected:#8C2E23;
  --status-rejected-bg:#FFE4DF;
  --status-withdrawn:#4F5661;
  --status-withdrawn-bg:#E7EAED;
  --font-ui:"Sarabun","Sarabun Fallback","Noto Sans Myanmar","Noto Sans",system-ui,sans-serif;
  --font-display:"Mitr","Mitr Fallback","Noto Sans Myanmar","Sarabun",sans-serif;
  --font-numeral:"Sarabun","Sarabun Fallback","Noto Sans Myanmar",sans-serif;
  --font-mono:"IBM Plex Mono",ui-monospace,monospace;
  --text-sm:.875rem;
  --text-xl:1.5rem;
  --radius-chip:10px;
  --radius-input:12px;
  --radius-tag:10px;
  --radius-card:18px;
  --radius-doc:8px;
  --radius-pill:999px;
  --shadow-card:0 1px 0 var(--color-rule-2),0 12px 28px -18px rgba(30,26,22,.35);
  --shadow-doc:6px 6px 0 var(--color-rule-2);
  --shadow-sheet:0 -4px 24px rgba(30,26,22,.16);
  --layout-read:640px;
  --layout-task:480px;
  font-family:var(--font-ui);
  color:var(--color-ink);
  background:var(--color-paper);
  font-synthesis:none;
}
*{box-sizing:border-box}
html,body{overflow-x:clip}
html{font-size:16px}
body{margin:0;min-width:320px;min-height:100vh;background:var(--color-paper);line-height:1.55}
:lang(my){line-height:1.65}
h1,h2{font-family:var(--font-display);font-style:normal;font-weight:700}
a{color:inherit}
button,input,select,textarea{font:inherit}
button,a,input,select,textarea,summary{-webkit-tap-highlight-color:transparent}
img{display:block;max-width:100%}
.skip-link{position:fixed;z-index:99;left:1rem;top:-5rem;min-height:48px;padding:.75rem 1rem;display:flex;align-items:center;background:var(--color-card);border:2px solid var(--color-primary);border-radius:var(--radius-input)}
.skip-link:focus{top:1rem}
.site-header{height:72px;display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:0 max(1rem,env(safe-area-inset-left));max-width:760px;margin:auto}
.wordmark{display:flex;align-items:center;gap:.5rem;min-height:48px;text-decoration:none;color:var(--color-primary);font-size:var(--text-xl);font-family:var(--font-display);line-height:1.4;white-space:nowrap}
.wordmark-glyph{width:24px;height:24px;flex:none;border-radius:var(--radius-chip);background:var(--color-primary)}
.wordmark strong{font-weight:700}
.language-menu{position:relative}
.language-menu summary{min-width:96px;min-height:48px;padding:0 .75rem;display:flex;align-items:center;justify-content:center;gap:.5rem;border:1px solid var(--color-muted);border-radius:var(--radius-input);background:var(--color-card);cursor:pointer;list-style:none}
.language-menu summary::-webkit-details-marker{display:none}
.language-options{position:absolute;right:0;z-index:10;top:54px;width:160px;padding:.35rem;background:var(--color-card);border-radius:var(--radius-card);box-shadow:var(--shadow-card)}
.language-options a{display:flex;align-items:center;min-height:48px;padding:0 .75rem;border-radius:var(--radius-chip);text-decoration:none}
.language-options a[aria-current=true]{background:var(--color-primary-tint);color:var(--color-primary-deep)}
.page{width:min(100%,760px);margin:auto;padding:1rem 1rem 7rem}
.job-page{max-width:calc(var(--layout-read) + 2rem)}
.job-hero{width:100%;background:var(--color-paper-2)}
.hero-image{width:100%;max-height:300px;aspect-ratio:16/9;object-fit:cover}
.fact-note{margin:.25rem 0 0;font-size:1rem;font-weight:400;line-height:1.6;color:var(--color-ink-2);overflow-wrap:anywhere}
.status-open{background:var(--status-hired-bg);color:var(--status-hired)}
.status-full{background:var(--status-completed-bg);color:var(--status-completed)}
.status-start_passed{background:var(--status-pending-bg,var(--color-paper-2));color:var(--color-ink-2)}
.status-expired,.status-missing,.status-closed{background:var(--status-withdrawn-bg);color:var(--status-withdrawn)}
/* Founder 2026-09-03 — pay-timing chip. Quiet paper by default; same_day gets
   the accent tint (mirrors .pay-timing-chip--accent in apps/web app.css). */
.status-pay-timing{background:var(--color-paper-2);color:var(--color-ink-2)}
.status-pay-timing-accent{background:var(--color-accent-tint);color:var(--color-ink)}
.text-action{display:inline-flex;align-items:center;min-height:48px;margin-top:.35rem;color:var(--color-primary);font-weight:700}
h2{margin:0 0 .6rem;font-size:1.125rem;line-height:1.4}
:lang(my) h2{line-height:1.5}
.verified{font-size:.875rem;background:var(--status-hired-bg);color:var(--status-hired);padding:.25rem .6rem;border-radius:var(--radius-pill);font-weight:700}
.primary{min-height:56px;padding:.75rem 1.25rem;border:0;border-radius:var(--radius-input);background:var(--color-primary);color:var(--color-primary-ink);text-decoration:none;font-weight:700;font-size:1.125rem;display:flex;align-items:center;justify-content:center;text-align:center;cursor:pointer;line-height:1.35}
.primary:active{background:var(--color-primary-deep);transform:translateY(1px)}
.primary:focus-visible,.text-action:focus-visible,.back-link:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,summary:focus-visible,a:focus-visible,.star-options input:focus-visible+svg,.tag-options input:focus-visible+span{outline:2px solid var(--color-focus);outline-offset:2px}
.primary:disabled{background:var(--color-paper-3);color:var(--color-muted);cursor:wait}
.desktop-action{display:none}
/* Human review #28 — "รับงานนี้" was smaller here than the SPA's. margin:auto
   on a grid item is an auto margin: it absorbs the free space, which cancels
   the default justify-self:stretch, so the button shrank to the width of its
   own label and sat centred. width + a horizontal-only auto margin keeps the
   centring AND the full width, at the SPA's 56px height (.primary). */
/* Astra UX audit #9 (founder-approved 2026-09-16) — the bar is the reading
   panel's width (--layout-read), and the button used to fill it: ~608px on
   a 1280 desktop, past the 480px cap § 11.2 puts on a task-shaped control.
   min(100%, --layout-task) keeps the phone full-width and centres a
   480px button in the bar on desktop. */
.sticky-action .primary{width:min(100%,var(--layout-task));margin:0 auto}
.detail-trust-line{width:min(100%,var(--layout-read));margin:0 auto;color:var(--color-ink-2);font-size:1rem;font-weight:500;line-height:1.55;text-align:center;overflow-wrap:anywhere}
/* Human review #28 — a tall empty gap between the card and the footer. The
   clearance under the job page exists for exactly one reason: the fixed
   .sticky-action bar covers the bottom of the viewport, so the page must be
   able to scroll that far past its last line. It was a hand-picked 10rem,
   which matched no real bar height; --sticky-action-h is measured from the
   real element by the inline script below and re-measured on resize,
   orientation change and webfont swap.

   Founder 2026-09-15 — the bar no longer carries the "ก่อนไปทำงาน" notice or
   the two trust lines (they are page content now), so its height no longer
   depends on a notice that may be open or closed. Its pieces, top to bottom:
   .75rem padding, the 56px primary, and a bottom padding that is .75rem OR
   the phone's gesture-bar inset, whichever is larger. That is
   --sticky-action-chrome. The only other thing that can move it is the label
   wrapping to a second line in Burmese (.75rem + 2 x 1.125rem/1.35 + .75rem
   inside the button = 74px), which is --sticky-action-max, the no-JS bound.
   The viewport-proportional cap that used to bound the open notice inside the
   bar is deleted with the notice.

   Luna review 2026-09-15 — the bound MUST carry the safe-area inset, because
   the bar's own bottom padding does: a fixed 6.25rem clearance on a phone
   with a 34px gesture bar left the footer's last links under the bar again.
   The inset reaches both through --safe-bottom, so the bar and the clearance
   cannot drift apart. --safe-bottom defaults to 0px and only becomes env()
   inside @supports (same pattern as apps/web/src/styles/app.css): a WebView
   that predates env() drops a bare env() DECLARATION, but inside a custom
   property the token survives parsing and poisons every property that
   substitutes it — here, the bar's padding and the page's clearance.
   The FALLBACK (no JS, or the window before the deferred script runs)
   is now exact rather than a bound, so the no-JS page is structurally
   non-overlapping with no :has selector and no script.

   The clearance is on <body> (.job-page-active, set by renderJobPage), not on
   <main>: the bar covers the bottom of the VIEWPORT, so the last thing on the
   page — the footer — is what must be able to scroll clear of it. On <main>
   it opened a dead band between the card and the footer AND still let the
   footer's last links sit under the bar. */
:root{--safe-bottom:0px;--sticky-action-pad-bottom:max(.75rem,var(--safe-bottom));--sticky-action-chrome:calc(.75rem + 56px + var(--sticky-action-pad-bottom));--sticky-action-max:calc(.75rem + 74px + var(--sticky-action-pad-bottom))}
@supports (padding-bottom: env(safe-area-inset-bottom)){
:root{--safe-bottom:env(safe-area-inset-bottom, 0px)}
}
.job-page-active{padding-bottom:calc(var(--sticky-action-h, var(--sticky-action-max)) + 1rem)}
.state-card .primary{margin-top:1.5rem}
footer{display:flex;flex-direction:column;align-items:center;padding:2.5rem 1rem 3rem;color:var(--color-muted);font-size:.875rem;text-align:center}
footer strong{color:var(--color-ink);font-size:1rem;font-family:var(--font-display)}
/* NM-036 — the age gate's three selects. One row on a phone, because a worker
   should see day/month/year as one question; each select keeps the 56px form
   height, so every target clears 48dp. */
.birth-date{border:0;padding:0;margin:0;min-width:0}
.birth-date legend{font-weight:500;font-size:.875rem;color:var(--color-ink-2);margin-bottom:.4rem;padding:0}
@media(min-width:414px){
.page{padding-left:1.5rem;padding-right:1.5rem}
.job-page,.record-page{max-width:calc(var(--layout-read) + 3rem)}
}
@media(min-width:700px){
.site-header{height:88px}
.page{padding-top:1.5rem}
.job-page-active{padding-bottom:calc(var(--sticky-action-h, var(--sticky-action-max)) + 1rem)}
}
@media(hover:hover) and (pointer:fine){
.primary:hover{background:var(--color-primary-hover)}
.language-options a:hover{background:var(--color-primary-tint);color:var(--color-primary-deep)}
}
.check-row{grid-template-columns:auto 1fr;align-items:start;gap:.75rem!important;font-weight:400!important}
.check-row input[type=checkbox]{width:28px!important;min-height:28px!important;margin-top:.15rem;accent-color:var(--color-primary)}
@media(prefers-reduced-motion:reduce){
*{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}
}
@media(forced-colors:active){
.status-chip,.verified,.notice,.record-stamp{border:1px solid currentColor}
.primary{border:2px solid ButtonText}
}

.landing-group{margin:1.5rem 0 .5rem;font-size:1rem;font-weight:700;color:var(--color-ink-2)}
.landing-page{max-width:720px;margin:0 auto;padding:0 16px 48px}
.landing-page h1{font-family:var(--font-display);font-size:clamp(1.5rem,5vw,2rem);line-height:1.35;margin:8px 0 4px}
.landing-explainer{margin:0 0 16px;color:var(--color-ink-2)}
.landing-count{margin:0 0 8px;font-weight:700}
.landing-count-inline{font-size:14px;font-weight:400;color:var(--color-muted)}
.landing-empty{margin:0 0 16px;padding:16px;background:var(--color-paper-2);border-radius:12px;color:var(--color-ink-2)}
.landing-jobs{list-style:none;margin:0 0 24px;padding:0;display:flex;flex-direction:column;gap:10px}
.landing-job a{display:flex;flex-direction:column;gap:4px;min-height:48px;padding:14px 16px;background:var(--color-card);border:1px solid var(--color-rule-2);border-radius:12px;text-decoration:none;color:var(--color-ink)}
.landing-job a:hover{border-color:var(--color-primary)}
.landing-job-row1{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.landing-job-title{font-size:20px;font-weight:700;line-height:1.4;overflow-wrap:anywhere}
.landing-job-pay{flex:0 0 auto;color:var(--color-primary-deep);font-weight:700}
/* § 6.1 employer row (founder 2026-09-09) — the shop's picture and name,
   under the title/pay row and above the facts. Same 32px round portrait and
   same quiet 14px ink-2 treatment as .job-card-shop in the SPA: the two
   cards must be indistinguishable in a screenshot. */
.landing-job-shop{display:flex;align-items:center;gap:8px;margin-top:4px;min-width:0;font-size:14px;color:var(--color-ink-2)}
.landing-job-shop-avatar{flex:0 0 auto;width:32px;height:32px;border-radius:50%;object-fit:cover;background:var(--color-paper-2)}
.landing-job-shop-initial{display:flex;align-items:center;justify-content:center;font-family:var(--font-display);font-size:14px;font-weight:600;line-height:1;color:var(--color-ink-2)}
.landing-job-shop-name{min-width:0;font-weight:600;overflow-wrap:anywhere}
/* Astra § 3.2 (founder-approved 2026-09-06) — the card's decision facts, one
   row each: a glyph plus the value, the label carried in the row's aria-label.
   16px ink, never a chip and never truncated. Replaces the joined meta string
   and the pay-timing chip. */
.landing-job-fact{display:flex;align-items:flex-start;gap:8px;color:var(--color-ink);font-size:16px;overflow-wrap:anywhere}
.landing-job-fact svg{flex:0 0 auto;width:20px;height:20px;margin-top:2px;color:var(--color-ink-2)}
.landing-job-slots{color:var(--color-ink);font-size:16px}
/* One action per card, and it navigates. 48px is a floor, so a wrapped label
   grows the row instead of clipping it. */
.landing-job-action{display:flex;align-items:center;justify-content:center;min-height:48px;margin-top:4px;border:1.5px solid var(--color-primary);border-radius:var(--radius-input);color:var(--color-primary);font-weight:700}
.landing-links{margin:0 0 20px}
.landing-links h2{font-family:var(--font-display);font-size:18px;margin:0 0 8px}
.landing-links h2 a{color:inherit}
.area-chips{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.area-chips a{display:inline-flex;align-items:center;min-height:48px;padding:0 14px;background:var(--color-paper-2);border-radius:999px;text-decoration:none;color:var(--color-ink)}
.area-chips a:hover{background:var(--color-primary-tint)}
.landing-station-line{margin:0 0 12px}
.landing-station-line h3{font-size:14px;font-weight:700;color:var(--color-muted);margin:0 0 6px}
.landing-region{margin:0 0 12px}
.landing-region h3{font-size:14px;font-weight:700;color:var(--color-muted);margin:0 0 6px}
.landing-post-cta{margin:8px 0 0;display:flex;flex-wrap:wrap;gap:16px}
/* Evergreen landing content (2026-09-04): the intro paragraph, the
   statutory-wage fact block and the per-page FAQ. The wage block is the
   only card here — it is a cited fact about the reader's own province and
   earns being visually separate from the prose around it. */
.landing-intro{margin:0 0 16px;color:var(--color-ink-2);line-height:1.6}
/* The live opener (2026-09-09): how many jobs are open here right now and
   what they pay. Measured numbers, so it leads the prose and carries the
   page's ink rather than the muted secondary tone. */
.landing-live{margin:0 0 10px;color:var(--color-ink);font-weight:600;line-height:1.6}
/* Astra public-SSR pass (2026-09-06) — the statutory minimum wage is a legal
   reference, not an offered price: it used to share the same bold tomato
   figure as an actual job's pay (.landing-job-pay), which reads as if the
   two were comparable amounts. Muted card, muted ink, no primary color —
   deliberately the opposite treatment from a job's price tag. */
.landing-wage{margin:0 0 20px;padding:14px 16px;background:var(--color-paper-2);border:1px solid var(--color-rule);border-radius:12px}
.landing-wage h2{font-family:var(--font-display);font-size:13px;margin:0 0 6px;color:var(--color-muted);text-transform:uppercase;letter-spacing:.02em}
.wage-fact{margin:0;font-size:16px;font-weight:600;color:var(--color-ink-2)}
.wage-note{margin:6px 0 0;font-size:14px;color:var(--color-ink-2);line-height:1.5}
.wage-source{margin:6px 0 0;font-size:13px;color:var(--color-muted)}
/* The area picker at the top of /หางาน and its hub — pick a place first.
   The long province/station lists collapse behind a native <details>. */
.landing-area-first{margin:0 0 24px}
.landing-more-areas{margin:12px 0 0}
.landing-more-areas>summary{cursor:pointer;min-height:48px;display:flex;align-items:center;color:var(--color-primary-deep);font-weight:700;list-style:none}
.landing-more-areas>summary::-webkit-details-marker{display:none}
.landing-more-areas[open]>summary{margin-bottom:8px}
/* Astra audit #4 (founder-approved 2026-09-16) — every category section's
   area chips sit behind the same disclosure, closed by default. The chips
   themselves are untouched: same labels, same order, same hrefs, still in the
   DOM (a crawler reads details content; only the viewport is spared). */
.landing-cat-areas{margin:0}
/* The site search (§ 6.6 / § 8): label above, full-width field, 56px primary.
   It used to be the browser's own control — a ~30px field with the button
   wrapping under it, the one place on the site that did not look like the
   rest of it. */
.landing-search{display:flex;flex-direction:column;gap:8px;margin:0 0 20px}
.landing-search label{font-weight:700;font-size:16px;color:var(--color-ink)}
.landing-search input[type=search]{width:100%;min-height:56px;padding:.75rem .9rem;border:1px solid var(--color-muted);border-radius:var(--radius-input);background:var(--color-card);color:var(--color-ink);font-family:inherit;font-size:1.125rem;-webkit-appearance:none;appearance:none}
.landing-search input[type=search]::-webkit-search-decoration,.landing-search input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}
.landing-search .primary{width:100%}
@media(min-width:700px){
.landing-search .primary{width:auto;align-self:flex-start;min-width:180px}
}
/* Zero-result state: alternatives are grouped under their own heading so
   they read as a distinct offer, not a continuation of "no jobs here". */
.landing-nearby-alternatives{margin:0 0 20px;padding:14px 16px;background:var(--color-paper-2);border-radius:12px}
.landing-nearby-alternatives>h2{font-family:var(--font-display);font-size:16px;margin:0 0 10px}
.landing-nearby-alternatives .landing-links{margin:0 0 14px}
.landing-nearby-alternatives .landing-links:last-child{margin-bottom:0}
.breadcrumbs ol{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:4px;font-size:14px;color:var(--color-muted)}
.breadcrumbs li+li::before{content:"›";margin:0 4px;color:var(--color-rule)}
.breadcrumbs a{color:var(--color-muted)}
/* NM employer guide (/หางาน/ลงประกาศงาน) — the same landing-page shell,
   plus a numbered step list and an FAQ definition list. */
.guide-steps{list-style:none;margin:0 0 20px;padding:0;display:flex;flex-direction:column;gap:12px}
.guide-step{display:flex;gap:12px;align-items:flex-start}
.guide-step-num{flex:none;width:32px;height:32px;border-radius:50%;background:var(--color-primary-tint);color:var(--color-primary-deep);font-weight:700;display:flex;align-items:center;justify-content:center}
.guide-step p{margin:0;padding-top:5px;line-height:1.55}
.guide-cta{margin:4px 0 24px}
.guide-faq{margin:0}
.guide-faq dt{font-weight:700;margin-top:14px}
.guide-faq dt:first-child{margin-top:0}
.guide-faq dd{margin:4px 0 0;padding-left:0;color:var(--color-ink-2)}

/* /for-employers (2026-09-09) — the three live example cards reuse the
   landing job-card styles verbatim; only the list wrapper is named here so
   the section can space itself. The three-step strip is the guide's step
   list laid out horizontally from 560px. */
.employer-examples{margin:0 0 24px}
.employer-examples .landing-jobs{margin:0}
.employer-example-note{margin:8px 0 0;font-size:14px;color:var(--color-muted)}
.employer-steps{list-style:none;margin:0 0 24px;padding:0;display:grid;gap:12px}
@media (min-width:560px){.employer-steps{grid-template-columns:repeat(3,1fr)}}
.employer-steps li{display:flex;gap:12px;align-items:flex-start}
.employer-steps .guide-step-num{flex:none}
.employer-steps p{margin:0;padding-top:5px;line-height:1.55}
.employer-payout{margin:0 0 24px;padding:14px 16px;background:var(--color-paper-2);border:1px solid var(--color-rule);border-radius:12px}
.employer-payout h2{font-family:var(--font-display);font-size:16px;margin:0 0 8px}
.employer-payout .about-list{margin:0}

/* NM employer landing (/หาคนงาน) — the landing-page shell plus a three-card
   benefit list. Cards stack on a phone and sit side by side from 560px,
   which is where three of them stop being unreadably narrow. */
.employer-benefits{list-style:none;margin:0;padding:0;display:grid;gap:12px}
@media (min-width:560px){
.employer-benefits{grid-template-columns:repeat(3,1fr)}
}
.employer-benefit{padding:14px 16px;background:var(--color-card);border:1px solid var(--color-rule-2);border-radius:12px}
.employer-benefit h3{font-family:var(--font-display);font-size:15px;margin:0 0 6px;line-height:1.4}
.employer-benefit p{margin:0;font-size:14px;color:var(--color-ink-2);line-height:1.55}
.employer-cta-note{margin:-16px 0 20px;font-size:14px;color:var(--color-muted)}
/* NM how-it-works (/วิธีใช้) — two numbered lists, phone first.
   The number is the landmark: it is large enough to scan down the page
   without reading, which is the whole point of a step guide for a reader
   who is on a cheap phone in a hurry. */
.howto-list{list-style:none;margin:0 0 28px;padding:0;display:flex;flex-direction:column;gap:10px;counter-reset:none}
.howto-step{display:flex;gap:14px;align-items:flex-start;padding:14px 16px;background:var(--color-card);border:1px solid var(--color-rule-2);border-radius:12px}
.howto-num{flex:none;width:40px;height:40px;border-radius:50%;background:var(--color-primary-tint);color:var(--color-primary-deep);font-family:var(--font-display);font-size:18px;font-weight:700;display:flex;align-items:center;justify-content:center}
.howto-body{min-width:0}
.howto-title{margin:0;font-weight:700;line-height:1.4}
.howto-detail{margin:4px 0 0;font-size:14px;color:var(--color-ink-2);line-height:1.55}
.howto-note{margin:-18px 0 24px;padding:12px 14px;background:var(--color-paper-2);border-radius:12px;font-size:14px;color:var(--color-ink-2);line-height:1.55}
/* Both CTAs clear 48dp on every screen; they stack on a phone so neither
   is ever a half-width tap target. */
.howto-ctas{display:flex;flex-wrap:wrap;gap:12px;margin:0 0 28px}
.howto-ctas a{display:flex;align-items:center;justify-content:center;min-height:48px;flex:1 1 220px;padding:12px 20px;border-radius:12px;font-weight:700;text-decoration:none}
.howto-ctas .howto-cta-primary{background:var(--color-primary);color:var(--color-primary-ink)}
.howto-ctas .howto-cta-primary:active{background:var(--color-primary-deep);transform:translateY(1px)}
.howto-ctas .howto-cta-secondary{background:var(--color-paper-2);color:var(--color-ink);border:1px solid var(--color-rule-2)}
/* Astra public-SSR pass (2026-09-06) — "หางาน" is the primary reading path;
   "ลงประกาศงาน?" is a disclosure so an employer visitor can open it, but a
   worker visitor is never asked to scroll past six posting steps first. */
.howto-disclosure{margin:0 0 8px;padding:0}
.howto-disclosure>summary{cursor:pointer;min-height:48px;display:flex;align-items:center;font-family:var(--font-display);font-size:18px;font-weight:700;color:var(--color-ink);list-style:none}
.howto-disclosure>summary::-webkit-details-marker{display:none}
.howto-disclosure>summary::before{content:"+";margin-right:8px;color:var(--color-primary-deep);font-weight:700}
.howto-disclosure[open]>summary::before{content:"−"}
/* Hallmark · macrostructure: Split Studio (brief-adapted) · locked design.md · Persuade
 * Pre-emit critique: P4 H4 E3 S4 R5 V4 (CSS reasoning; browser review pending).
 * Split reading guide → ruled process → real price-tag cards → employer band.
 * All rules are landing-scoped; no motion, invented figures or new tokens. */
.marketing-body .site-header{max-width:1200px;padding-inline:16px;gap:8px}
.marketing-body .wordmark{font-size:24px;gap:8px}
.marketing-body .wordmark-glyph{width:18px;height:18px}
.marketing-page{width:min(100%,1200px);max-width:1200px;padding:0 16px 48px}
.marketing-page :is(h1,h2,p,dt,dd){min-width:0;overflow-wrap:normal}
.marketing-page dd{overflow-wrap:anywhere}
.marketing-hero{display:grid;grid-template-columns:minmax(0,1fr);gap:32px;padding:32px 0 48px;align-items:center}
.marketing-intro,.marketing-employer-copy{min-width:0}
.marketing-body:lang(my) .marketing-page :is(h1,h2){line-height:1.65}
.marketing-page h1{font-size:clamp(2rem,4.3vw,3.5rem);line-height:1.35;max-width:21ch;margin:0 0 20px}
.marketing-lede{margin:0 0 24px;max-width:48ch;font-size:1.125rem;line-height:1.65;color:var(--color-ink-2)}
.marketing-cta{margin:0;display:flex;min-width:0}
.marketing-cta .primary{width:100%;min-height:56px;white-space:nowrap;padding-inline:16px;transition:none;transform:none}
.marketing-preview{min-width:0;padding:24px;background:var(--color-paper-2);border-radius:var(--radius-card)}
.marketing-preview h2{font-size:1.25rem;line-height:1.5;margin:0 0 24px}
.marketing-preview dl{margin:0}
.marketing-preview-fact{padding:16px 0;border-top:1px solid var(--color-rule)}
.marketing-preview-fact:last-child{padding-bottom:0}
.marketing-preview dt{display:flex;align-items:center;gap:12px;font-size:1.25rem;font-weight:700}
.marketing-preview dt svg{width:24px;height:24px;flex:none;color:var(--color-primary)}
.marketing-preview dd{margin:8px 0 0 36px;color:var(--color-ink-2);font-size:1rem}
.marketing-how{padding:32px 0;border-block:1px solid var(--color-rule)}
.marketing-page :is(.marketing-how,.marketing-jobs,.marketing-employers) h2{font-size:clamp(1.375rem,2.2vw,1.75rem);line-height:1.5;margin:0 0 24px;text-wrap:balance}
.marketing-steps{margin:0;padding-left:24px;display:grid;grid-template-columns:minmax(0,1fr);gap:24px}
.marketing-step{padding-left:8px;min-width:0}
.marketing-step::marker{font-family:var(--font-numeral);font-weight:700;color:var(--color-primary)}
.marketing-step-title{margin:0 0 8px;font-weight:700;font-size:1.125rem}
.marketing-step-detail{margin:0;color:var(--color-ink-2);line-height:1.65}
.marketing-jobs{padding:48px 0 0}
.marketing-jobs .landing-jobs{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;margin:0;align-items:start}
.marketing-jobs .landing-job{min-width:0}
.marketing-jobs .landing-job a{padding:20px;border-radius:var(--radius-card);gap:12px}
.marketing-jobs .landing-job-row1{flex-wrap:wrap;gap:12px}
.marketing-jobs .landing-job-title{font-family:var(--font-display);font-weight:600;flex:1 1 160px;min-width:0}
.marketing-jobs .landing-job-pay{font-family:var(--font-numeral);font-size:22px;line-height:1.5;padding:6px 10px;background:var(--color-tag-ink);color:var(--color-paper);border-radius:var(--radius-tag);max-width:100%;overflow-wrap:break-word;flex-shrink:1}
.marketing-jobs :is(.landing-job-fact,.landing-job-shop-name){overflow-wrap:break-word}
.marketing-jobs .landing-job-fact>span{min-width:0}
.marketing-jobs .landing-job-action{border:0;border-top:1px solid var(--color-rule-2);border-radius:0;justify-content:flex-start;white-space:nowrap}
.marketing-employers{margin-top:48px;padding:24px;background:var(--color-paper-2);border-radius:var(--radius-card);display:grid;grid-template-columns:minmax(0,1fr);gap:24px;align-items:center}
.marketing-page .marketing-employers h2{margin-bottom:12px}
.marketing-employers .marketing-lede{margin:0}
.marketing-employers .primary{background:var(--color-paper);color:var(--color-primary);border:1.5px solid var(--color-primary)}
.marketing-body footer{max-width:1200px;margin:auto;padding:24px 16px 40px;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:8px 24px;text-align:left;border-top:1px solid var(--color-rule)}
.marketing-body footer strong{font-size:1.25rem}
.marketing-body footer>span{flex-basis:calc(100% - 120px)}
.marketing-body footer>a{display:inline-flex;align-items:center;min-height:48px;white-space:nowrap;font-size:1rem;color:var(--color-ink-2)}
.marketing-body footer .detail-trust-line{flex-basis:100%;margin:16px 0 0;font-size:1rem}
.marketing-body :is(a,summary):focus-visible{outline:2px solid var(--color-focus);outline-offset:4px}
@media(hover:none){
.marketing-cta .primary:active{background:var(--color-primary);transform:none}
.marketing-employers .primary:active{background:var(--color-paper)}
}
@media(hover:hover){
.marketing-employers .primary:hover{background:var(--color-primary);color:var(--color-primary-ink)}
.marketing-body footer>a:hover{color:var(--color-primary)}
.marketing-cta .primary:active{background:var(--color-primary-deep);color:var(--color-primary-ink);transform:none}
}
@media(min-width:414px){
.marketing-body .site-header,.marketing-page{padding-inline:24px}
.marketing-body footer{padding-inline:24px}
}
@media(max-width:767px){
.marketing-preview{padding:16px}
.marketing-preview h2{font-size:1rem;margin-bottom:12px}
.marketing-preview dl{display:flex;flex-wrap:wrap;gap:8px 20px}
.marketing-preview-fact{padding:0;border:0}
.marketing-preview dt{font-size:1rem;gap:4px;white-space:nowrap}
.marketing-preview dt svg{width:16px;height:16px}
.marketing-preview dd{display:none}
.marketing-employers .primary{width:auto;min-height:48px}
.marketing-page .marketing-employers h2{font-size:1.125rem}
}
@media(max-width:479px){
.marketing-body footer>a{flex-basis:100%}
}
@media(min-width:768px){
.marketing-hero{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:32px;padding:48px 0 56px}
.marketing-preview{padding:24px}
.marketing-cta .primary{width:auto;min-width:240px}
.marketing-steps{grid-template-columns:repeat(3,minmax(0,1fr));column-gap:40px}
.marketing-jobs .landing-jobs{grid-template-columns:repeat(2,minmax(0,1fr))}
.marketing-employers{padding:32px;grid-template-columns:minmax(0,1fr) auto;gap:32px}
}
@media(min-width:1024px){
.marketing-hero{gap:64px;padding:64px 0}
.marketing-preview{padding:32px}
.marketing-how{padding:40px 0}
.marketing-jobs .landing-jobs{grid-template-columns:repeat(3,minmax(0,1fr))}
}

