/* OD-LAYOUT-PRIMITIVES v1 — structure only: display, flex/grid, overflow, wrapping, ratio, geometry.
   Put this @layer first; product CSS outside the layer always wins. */
@layer od-layout {
  :where(.od-stack,.od-row,.od-row-top,.od-cluster,.od-grid,.od-field,.od-stat,.od-cell,.od-tile) > :where(*) { min-width: 0; }

  /* containers */
  .od-stack   { display: flex; flex-direction: column; gap: var(--od-gap, 8px); }
  .od-row     { display: flex; align-items: center; gap: var(--od-gap, 8px); }
  .od-row-top { display: flex; align-items: flex-start; gap: var(--od-gap, 8px); }
  .od-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--od-gap, 8px); }
  .od-fill    { flex: 1 1 0; min-width: 0; }
  .od-fixed   { flex: none; }
  .od-grid    { display: grid; gap: var(--od-gap, 12px); grid-template-columns: repeat(var(--od-cols, 3), minmax(0, 1fr)); }

  /* stacked information: each piece is its own line — never sibling inline spans */
  .od-stat, .od-field, .od-cell { display: grid; gap: var(--od-gap, 2px); }
  :where(.od-stat,.od-field,.od-cell) > :where(*) { display: block; }
  .od-tile { display: grid; grid-template-rows: auto 1fr; }
  :where(.od-tile) > :where(*) { display: block; }

  /* media keeps its intrinsic ratio by default; never a distorted or cropped
     cover by accident. height:auto lets the ratio win over an <img height="…">
     attribute. Cropping to a uniform box is an explicit opt-in: set --od-ratio
     AND add .od-media-cover together (per the core rule, only where a crop is
     deliberate — tile thumbs, decorative fills — never on full-frame content). */
  .od-media { display: block; width: 100%; height: auto; aspect-ratio: var(--od-ratio, auto); }
  .od-media-cover { object-fit: cover; }

  /* functional inline SVG icons opt into bounded geometry; content SVGs keep their own */
  .od-icon { display: inline-block; inline-size: var(--od-icon-size, 1em); block-size: var(--od-icon-size, 1em); flex: none; }

  /* data text only — authored copy is rewritten to its budget instead */
  .od-truncate { display: block; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .od-clamp-2, .od-clamp-3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
  .od-clamp-2 { -webkit-line-clamp: 2; }
  .od-clamp-3 { -webkit-line-clamp: 3; }
  .od-lines-2 { min-height: calc(2 * 1.4em); }   /* block-level reservation for a shared baseline */
  .od-nowrap  { white-space: nowrap; }           /* 数字+单位 · 价格+起 · 日期+星期 */
  .od-keep    { word-break: keep-all; overflow-wrap: anywhere; } /* CJK labels break at spaces / <wbr> first */

  /* screen skeleton (optional): bars take their own space, the middle scrolls — no padding guessed for chrome */
  .od-screen { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; height: 100%; }
  .od-scroll { overflow-y: auto; overscroll-behavior: contain; min-height: 0; }

  /* horizontal rail: the next item peeks at the edge; trailing room survives overflow */
  .od-rail { display: flex; gap: var(--od-gap, 8px); overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none;
             padding-inline: var(--od-rail-pad, 16px); scroll-padding-inline: var(--od-rail-pad, 16px); }
  .od-rail::-webkit-scrollbar { display: none; }
  :where(.od-rail) > :where(*) { flex: none; scroll-snap-align: start; }
  :where(.od-rail) > :where(:last-child) { margin-inline-end: var(--od-rail-pad, 16px); }

  .od-spacer { flex: none; visibility: hidden; pointer-events: none; }
  .od-touch  { min-width: 44px; min-height: 44px; }
}
/* /OD-LAYOUT-PRIMITIVES v1 */

:root {
 color-scheme:light;
 --bg:#f5f6f2;--bg-sunken:#eef0eb;--surface:#ffffff;--surface-2:#f9faf7;--surface-3:#eef0eb;--overlay:rgba(12,15,13,.5);
 --border:#dde1da;--border-strong:#c9cec6;--control-border:#858e87;
 --text:#101512;--text-2:#3d4641;--text-3:#5a645e;--text-on-accent:#ffffff;
 --accent:#0e4a37;--accent-hover:#07291f;--accent-soft:#f3f8e4;--accent-soft-text:#1f3a0a;--accent-ring:rgba(14,74,55,.22);
 --lime:#cff26a;--on-lime:#101512;--panel:#101512;--panel-text:#e9eeea;
 --ok:#286e44;--ok-soft:#e4f2e8;--warn:#805600;--warn-soft:#f7edd3;--danger:#b23a32;--danger-hover:#942e27;--danger-soft:#f8e5e3;--text-on-danger:#ffffff;--info:#2f5f9e;--info-soft:#e4ecf7;
 --r-xs:4px;--r-sm:8px;--r-md:10px;--r-lg:12px;--r-xl:14px;--r-pill:999px;
 --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:24px;--sp-6:32px;--sp-7:48px;--sp-8:64px;--sp-9:96px;
 --font-ui:"IBM Plex Sans","Noto Sans Bengali",system-ui,sans-serif;--font-display:"Schibsted Grotesk","Noto Sans Bengali",system-ui,sans-serif;--font-bn:"Noto Sans Bengali","IBM Plex Sans",sans-serif;--font-mono:"IBM Plex Mono",ui-monospace,Consolas,monospace;
 --fs-xs:.8125rem;--fs-sm:.875rem;--fs-base:1rem;--fs-md:1.0625rem;--fs-lg:1.25rem;--fs-xl:1.5rem;--fs-2xl:2rem;--fs-3xl:2.75rem;--lh-tight:1.12;--lh-snug:1.4;--lh-normal:1.6;
 --shadow-sm:0 1px 2px #10151208;--shadow-md:0 4px 16px #1015120a;--shadow-lg:0 12px 32px #10151225;
 --dur-fast:120ms;--dur:180ms;--dur-slow:240ms;--ease-out:cubic-bezier(.16,.84,.44,1);--ease-in:cubic-bezier(.5,0,.75,0);
 --sidebar-w:288px;--topbar-h:68px;--measure:860px;--z-sidebar:40;--z-topbar:30;--z-drawer:60;--z-modal:70;--z-toast:80;--od-gap:8px;
}
[data-theme="dark"] {
 color-scheme:dark;--bg:#0f1012;--bg-sunken:#121316;--surface:#17181b;--surface-2:#1c1d21;--surface-3:#25272c;--overlay:rgba(0,0,0,.65);
 --border:#2a2c31;--border-strong:#3a3d44;--control-border:#686e78;--text:#ecedef;--text-2:#c4c7cd;--text-3:#9599a2;--text-on-accent:#0f1012;
 --accent:#cff26a;--accent-hover:#ddf88e;--accent-soft:#25282d;--accent-soft-text:#ddf29a;--accent-ring:rgba(207,242,106,.2);--panel:#1a1b1f;
 --ok:#82d5a1;--ok-soft:#16301f;--warn:#e0b85f;--warn-soft:#332a15;--danger:#ef8378;--danger-hover:#f5a099;--danger-soft:#3a1f1d;--text-on-danger:#321410;--info:#86b2ec;--info-soft:#1a2537;
 --shadow-sm:0 1px 2px #0002;--shadow-md:0 4px 16px #0002;--shadow-lg:0 16px 44px #0006;
}
html[lang="bn"]{--font-ui:var(--font-bn);--font-display:var(--font-bn)}
