/* ============================================================================
   PTCARGO · shared/css/layout.css   (Design System · Layer 2 of 4)
   ----------------------------------------------------------------------------
   Structure only — containers, grids, and the primitives that arrange things.
   Uses --space-* / --radius-* tokens ONLY. No brand colors and no buttons here
   (those live in components.css). The one exception the work-order allows:
   .card / .panel may carry a surface background + hairline + shadow token.
   Requires tokens.css to be loaded first.   Phase 1 does NOT touch any .html.
   ========================================================================== */

/* ---- page container ------------------------------------------------------ */
.container {
  width: 100%;
  max-width: 1120px;
  margin-inline: auto;
  padding-inline: var(--space-4);
}
.container-narrow { max-width: 760px; }
.container-wide   { max-width: 1360px; }

/* ---- grid ---------------------------------------------------------------- */
.grid {
  display: grid;
  gap: var(--space-4);
}
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-auto { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

/* ---- flow rows / columns ------------------------------------------------- */
.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.col {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* ---- stack (vertical rhythm) & cluster (inline group) -------------------- */
.stack   { display: flex; flex-direction: column; gap: var(--space-3); }
.stack-sm { gap: var(--space-2); }
.stack-lg { gap: var(--space-5); }

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* ---- centering ----------------------------------------------------------- */
.center {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---- toolbar (title left, actions right) --------------------------------- */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-2);
}

/* ---- sidebar + content --------------------------------------------------- */
.sidebar {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}

/* ---- surfaces: card & panel (surface bg + line + shadow tokens allowed) --- */
.card {
  background: var(--color-surface);          /* white (#fff) — ONE card look system-wide */
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg, 20px);     /* Owner card spec 2026-07-18: rounded 20px */
  box-shadow: var(--shadow-md);
  padding: var(--sp-card-pad, 16px);         /* CLASS_MAP §B — inner card padding, single source */
}
.panel {
  background: var(--color-surface-2);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.card-flush { padding: 0; }

/* ---- responsive: collapse multi-column layouts on small screens ---------- */
@media (max-width: 720px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .sidebar { grid-template-columns: 1fr; }
}

/* ============================================================================
   CANONICAL VOCABULARY — page skeleton + structure (CLASS_MAP 2026-07-18)
   ----------------------------------------------------------------------------
   The Owner-defined class names every page uses system-wide. Added here (folded
   from the retired shared/css/pt-layout.css pilot + CLASS_MAP §A/§B) so there is
   ONE source. Spacing flows through the --sp-* tokens. The existing rules above
   (.container/.grid/.row/.col/.card/.panel/.stack/…) are KEPT unchanged so the
   55 pages already loading this file are not disturbed.

   TOKEN NOTE: the page-skeleton rules below (header.hd/.title/.pybar/.hero*)
   read the LEGACY alias tokens (--line/--ink/--fd/--paper/--sun/--clay/…) that
   the member/mobile pages theme in their own :root — this keeps the pilot
   (account-hub) byte-identical to the retired pt-layout.css and lets each page's
   theme flow through. tokens.css maps every legacy alias to a --color-* default.
   ============================================================================ */

/* ---- page header bar  (folded from pt-layout header.hd) -------------------
   Scoped to header.hd DELIBERATELY: nested sheet headers use <div class="hd">
   and must NOT inherit sticky/blur/border chrome. Base skeleton header is always
   <header class="hd">. Only account-hub uses the compound form today, so this
   selector cannot affect the other shared-CSS pages (they use bare <header>).   */
header.hd {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 12px;
  background: rgba(255, 248, 242, .92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line, #f2e6d8);
}

/* ---- .page — page content wrapper (was .wrap) · outer page padding -------- */
.page { padding: var(--sp-page, 16px); }

/* ---- uniform vertical rhythm between skeleton blocks (CLASS_MAP §B) --------
   THE mechanism that makes "ช่องว่างเท่ากันทั้งระบบ" real: every .card that
   follows a sibling inside main.page gets the SAME gap from the single --sp-card
   token. Scoped to `main.page >` so it only governs skeleton-conformant pages
   (the ones we convert) and never disturbs cards nested in .stack/.grid/.sidebar
   layouts on the 55 legacy design-system pages. First block sits flush to the
   .page padding. Pages MUST NOT set their own margin/padding on .page/.card —
   spacing flows from here only.                                                */
main.page > * + .card { margin-top: var(--sp-card, 14px); }
main.page > .card:first-child { margin-top: 0; }

/* ---- .title — page / section title (was .sechd / htitle / st) ------------- */
.title {
  display: flex; align-items: center; gap: 7px;
  margin: 0 0 11px;
  font-family: var(--fd, 'Mitr', sans-serif);
  font-weight: 600; font-size: 14px;
  color: var(--ink, #2a2016);
}

/* ---- .pybar — fixed bottom action bar (folded from pt-layout) -------------
   Mobile = fixed to the viewport foot. On desktop the AppShell neutralises the
   fixed position so the bar flows inline beside the sidebar (the two cooperate). */
.pybar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: flex; align-items: center; gap: var(--sp-gap, 8px);
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: var(--paper, #fff);
  border-top: 1px solid var(--line, #f2e6d8);
  box-shadow: 0 -8px 24px -16px rgba(120, 70, 20, .4);
}

/* ---- .hero + variants — full-width top banner (CLASS_MAP §6.5) ------------
   base = structure only (relative + clip + padding); the variant carries the
   fill + white text. Full-bleed by DOM placement (put the hero OUTSIDE .page's
   padding), matching the existing member/mobile hero pattern.                  */
.hero {
  position: relative;
  overflow: hidden;
  padding: 22px 16px 24px;
}
.hero1, .hero2, .hero3 { color: #fff; }
.hero1 { background: linear-gradient(120deg, var(--sun, #ff7a1a), var(--sun-deep, #ef5f06)); }        /* standard orange */
.hero2 { background: linear-gradient(120deg, var(--clay, #c8692b), var(--clay-deep, #a9531f)); }      /* coffee / member  */
.hero3 { background: linear-gradient(120deg, var(--ember, #ff3d2e), var(--red-d, #b03a30)); }         /* flash / hot      */

/* ---- 8-slot proportional column spans (used inside a flex .row) -----------
   .col-N shares a .row proportionally (N of 8). Pairs with the existing flex
   .row above. min-width:0 keeps long content from overflowing.                 */
.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8 { min-width: 0; }
.col-1 { flex: 1 1 0; }
.col-2 { flex: 2 1 0; }
.col-3 { flex: 3 1 0; }
.col-4 { flex: 4 1 0; }
.col-5 { flex: 5 1 0; }
.col-6 { flex: 6 1 0; }
.col-7 { flex: 7 1 0; }
.col-8 { flex: 8 1 0; }
/* responsive class-kit (Owner 2026-07-18): mobile = each column stacks full-width;
   desktop (>640px) = proportional side-by-side. So `.col-8 + .col-4` = 2-col 66/33 and
   `.col-4 ×3` = 3 equal cols on desktop, all stacked on phones. Author picks widths by N. */
@media (max-width: 640px) {
  .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8 { flex-basis: 100%; }
}

/* ============================================================================
   DESKTOP KIT (Owner 2026-07-18) — "awesome kit": one shared source, every page
   auto-improves on wide screens. (a) buttons stop being full-width blocks;
   (b) opt-in multi-column page layout.
   ============================================================================ */
@media (min-width: 1024px) {
  /* (a) Buttons size to their content on desktop (mobile keeps full-width CTAs).
     High specificity so it beats page-local `.btn{width:100%;display:flex}`.
     Opt back into full-width with .block / .btn-block (e.g. a form submit).      */
  main.page .btn:not(.block):not(.btn-block):not(.full),
  main.page .button:not(.block):not(.btn-block):not(.full) {
    display: inline-flex;
    width: auto;
    align-self: flex-start;
  }

  /* (b) Opt-in desktop multi-column content: <main class="page cols2"> (or cols3).
     Cards auto-flow into columns; grid gap owns spacing; a full-width block uses
     .card.wide, and a hero / a section heading (.title as a direct child) spans
     all columns. Mobile stays single-column (this whole block is desktop-only).  */
  main.page.cols2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-card, 14px); align-items: start; }
  main.page.cols3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-card, 14px); align-items: start; }
  main.page.cols2 > .card, main.page.cols3 > .card { margin-top: 0; }
  main.page.cols2 > .card.wide, main.page.cols3 > .card.wide,
  main.page.cols2 > .hero,      main.page.cols3 > .hero,
  main.page.cols2 > .title,     main.page.cols3 > .title { grid-column: 1 / -1; }
}

/* Extend the button-de-stretch below 1024 for the app-shell desktop (Owner 2026-07-21):
   from 768px up, buttons on real desktop (body.ptshell) size to their content instead of
   staying full-width mobile bars. Scoped to body.ptshell so phone-frame pages are NOT
   affected. Mobile (<768) keeps full-width CTAs. Opt back into full-width with
   .block / .btn-block / .full (e.g. a form submit that should fill its card).            */
@media (min-width: 768px) {
  body.ptshell main.page .btn:not(.block):not(.btn-block):not(.full),
  body.ptshell main.page .button:not(.block):not(.btn-block):not(.full) {
    display: inline-flex;
    width: auto;
    align-self: flex-start;
  }
}

/* ---- .nav — horizontal in-content nav / pill scroller (was navrow) -------- */
.nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ---- typography classes (headings + body as classes) --------------------- */
.h1 { font-family: var(--fd, 'Mitr', sans-serif); font-weight: 700; font-size: var(--font-2xl, 26px); line-height: var(--line-tight, 1.25); margin: 0; color: var(--ink); }
.h2 { font-family: var(--fd, 'Mitr', sans-serif); font-weight: 600; font-size: var(--font-xl, 20px);  line-height: var(--line-tight, 1.25); margin: 0; color: var(--ink); }
.h3 { font-family: var(--fd, 'Mitr', sans-serif); font-weight: 600; font-size: var(--font-lg, 16px);  line-height: var(--line-tight, 1.25); margin: 0; color: var(--ink); }
.h4 { font-family: var(--fd, 'Mitr', sans-serif); font-weight: 600; font-size: var(--font-md, 14px);  line-height: var(--line-tight, 1.25); margin: 0; color: var(--ink); }
.h5 { font-family: var(--fd, 'Mitr', sans-serif); font-weight: 600; font-size: var(--font-sm, 13px);  line-height: var(--line-tight, 1.25); margin: 0; color: var(--ink); }
.h6 { font-family: var(--fd, 'Mitr', sans-serif); font-weight: 600; font-size: var(--font-xs, 11px);  line-height: var(--line-tight, 1.25); margin: 0; color: var(--ink); letter-spacing: .04em; text-transform: uppercase; }
.p  { font-family: var(--fb, 'Prompt', sans-serif); font-size: var(--font-md, 14px); line-height: var(--line-normal, 1.5); color: var(--ink); margin: 0 0 var(--space-3); }

/* ============================================================================
   CLASS_MAP additions (2026-07-18b) — ADDITIVE ONLY (track-parcel pilot)
   คลาสใหม่ตาม vocab (+เลข) · ไม่แก้กฎเดิม → 55 หน้าไม่กระทบ · token-driven
   ============================================================================ */
/* hero4 — hero การ์ดพื้นสว่าง (ต่างจาก .hero1-3 ที่เป็นพื้นสี) */
.hero4 { background: var(--color-surface); border: 1px solid var(--color-line); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: var(--space-6); color: var(--color-text); }
/* steps — แถว process (ไอคอน+ข้อความ) */
.steps {grid-template-columns: repeat(2, minmax(0,1fr));gap: var(--space-2);}
.step {
    display: flex;
    gap: 13px;
    padding: 13px 0px 13px 0px;
    border-bottom: 1px dashed var(--line);
    animation: pop .4s ease both;
}
.step .step-ic { width: 44px; height: 44px; border-radius: var(--radius-md); display: grid; place-items: center; margin: 0 auto var(--space-2); background: var(--color-primary-soft); color: var(--color-primary); }
.step .step-ic svg { width: 22px; height: 22px; }
.step b { font-family: var(--font-display, 'Mitr', sans-serif); font-weight: 600; font-size: var(--font-sm, 13px); display: block; line-height: 1.3; color: var(--color-text); }
.step span {font-size: var(--font-xs, 20px);color: #ffffff;line-height: 1.4;display: block;margin-top: 3px;text-align: center;align-content: center;}
@media (min-width: 720px) { .steps { grid-template-columns: repeat(5, minmax(0,1fr)); } }
/* timeline — ไทม์ไลน์สถานะแนวตั้ง */
.timeline { display: flex; flex-direction: column; }
.tl-item { display: flex; gap: var(--space-3); padding-bottom: var(--space-4); position: relative; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item .tl-dot { width: 26px; height: 26px; border-radius: 50%; flex: none; display: grid; place-items: center; color: #fff; background: var(--color-line-strong); z-index: 1; }
.tl-item .tl-dot svg { width: 14px; height: 14px; }
.tl-item.is-done .tl-dot { background: var(--color-success); }
.tl-item.is-now  .tl-dot { background: var(--color-primary); }
.tl-item::before { content: ""; position: absolute; left: 12px; top: 28px; bottom: -2px; width: 2px; background: var(--color-line); }
.tl-item:last-child::before { display: none; }
.tl-item.is-done::before { background: var(--color-success); }
.tl-item .tl-body { flex: 1; min-width: 0; padding-top: 2px; }
.tl-item .tl-body b { font-family: var(--font-display, 'Mitr', sans-serif); font-weight: 600; font-size: var(--font-md, 14px); display: block; line-height: 1.35; color: var(--color-text); }
.tl-item.is-pending .tl-body b { color: var(--color-muted); }
.tl-item .tl-body span { font-size: var(--font-sm, 13px); color: var(--color-text-soft); }
/* boxed page — จัดเนื้อหากึ่งกลาง จำกัดความกว้าง (เลือกใช้ด้วย <main class="page boxed">) */
.page.boxed { max-width: 1430px; margin-inline: auto; }
