/* ==========================================================================
   Typefaces
   Inter (UI) and Fraunces (display) are self-hosted rather than pulled from a
   CDN: the Content-Security-Policy allows `font-src 'self'` only, so a linked
   Google Fonts stylesheet would be refused by the browser and every heading
   would silently fall back to Georgia.

   Both are variable fonts carrying their whole weight range in one file, and
   `unicode-range` keeps a Latin page from ever fetching the extended cuts.
   Fraunces is pinned to a single optical size (24) and the 400-800 weights the
   design actually uses, which halves it from 66KB to 33KB.

   Noto Sans Bengali is subset to the currency signs and Bengali digits alone --
   4KB rather than 105KB -- because the store prices in taka (U+09F3) and that
   one glyph appears beside every price on the site. Bengali prose still falls
   through to the reader's system font, exactly as it did before.

   Licences: Inter, Fraunces and Noto Sans Bengali are all SIL Open Font
   License 1.1. See wwwroot/fonts/OFL.txt.
   ========================================================================== */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/fraunces-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/fraunces-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Noto Sans Bengali";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/noto-sans-bengali-currency.woff2") format("woff2");
  unicode-range: U+0964-0965, U+09E6-09EF, U+09F2-09F3, U+09F9;
}

/* ---- Metric-matched fallbacks ------------------------------------------
   `font-display: swap` paints a system font first and replaces it when the
   webfont lands. If the two measure differently the text re-wraps on arrival
   and everything under it moves: that swap was the whole of an intermittent
   0.197 layout shift on the home page, contributed by the hero headline.

   These two faces are the system fallbacks re-proportioned to match. The
   `size-adjust` figure is the ratio of average character width between the
   webfont and the system font, measured over letter-frequency-weighted English
   text, and the ascent/descent overrides give the fallback the same line box.
   Substituting one for the other then changes the letterforms without moving a
   single line. Regenerate with scripts/genfallback.py if either face changes.

   Values are derived from the shipped files, not guessed. -------------------- */

@font-face {
  font-family: "Inter Fallback";
  src: local("Segoe UI"), local("Helvetica Neue"), local("Arial");
  size-adjust: 107.14%;
  ascent-override: 90.42%;
  descent-override: 22.51%;
  line-gap-override: 0.00%;
}

@font-face {
  font-family: "Fraunces Fallback";
  src: local("Georgia"), local("Times New Roman");
  size-adjust: 113.57%;
  ascent-override: 86.11%;
  descent-override: 22.45%;
  line-gap-override: 0.00%;
}

/* ==========================================================================
   Bongeeo design system
   Design tokens, reset and primitives. Every component file below this one
   composes from these tokens, so the whole storefront can be re-themed by
   editing this file alone.
   ========================================================================== */

:root {
  /* ---- Brand palette --------------------------------------------------- */
  --brand-50: #eefbf7;
  --brand-100: #d3f5ea;
  --brand-200: #a9ead7;
  --brand-300: #74d8be;
  --brand-400: #40bd9f;
  --brand-500: #1fa285;
  --brand-600: #12836c;
  --brand-700: #0f6959;
  --brand-800: #105448;
  --brand-900: #0f463d;

  --accent-400: #f0a04b;
  --accent-500: #e07f2c;
  --accent-600: #c26520;

  /* ---- Neutrals -------------------------------------------------------- */
  --ink-50: #f8fafc;
  --ink-100: #f1f5f9;
  --ink-200: #e2e8f0;
  --ink-300: #cbd5e1;
  --ink-400: #94a3b8;
  --ink-500: #64748b;
  --ink-600: #475569;
  --ink-700: #334155;
  --ink-800: #1e293b;
  --ink-900: #0f172a;

  /* ---- Semantic -------------------------------------------------------- */
  --success-50: #ecfdf5;
  --success-500: #10b981;
  --success-700: #047857;
  --warning-50: #fffbeb;
  --warning-500: #f59e0b;
  --warning-700: #b45309;
  --danger-50: #fef2f2;
  --danger-500: #ef4444;
  --danger-600: #dc2626;
  --danger-700: #b91c1c;
  --info-50: #eff6ff;
  --info-500: #3b82f6;
  --info-700: #1d4ed8;

  /* ---- Surfaces -------------------------------------------------------- */
  --surface: #ffffff;
  --surface-raised: #ffffff;
  --surface-sunken: var(--ink-50);
  --surface-inverse: var(--ink-900);
  --border: var(--ink-200);
  --border-strong: var(--ink-300);

  /* ---- Text ------------------------------------------------------------ */
  --text-primary: var(--ink-900);
  --text-secondary: var(--ink-600);
  --text-muted: var(--ink-500);
  --text-inverse: #ffffff;
  --text-link: var(--brand-700);

  /* ---- Typography ------------------------------------------------------ */
  /* "Noto Sans Bengali" sits directly after Inter rather than at the end of the
     stack. Font matching runs per glyph, so the taka sign beside every price
     resolves to the subset webfont above instead of to whichever Bengali face
     the reader's operating system happens to ship. */
  --font-sans: "Inter", "Noto Sans Bengali", "Inter Fallback", -apple-system,
    BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Fraunces", "Fraunces Fallback", "Playfair Display", Georgia,
    "Times New Roman", serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* A fluid type scale: sizes track the viewport between 360px and 1440px. */
  --text-2xs: 0.6875rem;
  --text-xs: 0.75rem;
  --text-sm: 0.8125rem;
  --text-base: clamp(0.875rem, 0.84rem + 0.15vw, 0.9375rem);
  --text-md: clamp(0.9375rem, 0.9rem + 0.2vw, 1.0625rem);
  --text-lg: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  --text-xl: clamp(1.25rem, 1.15rem + 0.45vw, 1.5rem);
  --text-2xl: clamp(1.5rem, 1.3rem + 0.9vw, 2rem);
  --text-3xl: clamp(1.875rem, 1.5rem + 1.6vw, 2.75rem);
  --text-4xl: clamp(2.25rem, 1.7rem + 2.4vw, 3.5rem);

  --leading-tight: 1.15;
  --leading-snug: 1.35;
  --leading-normal: 1.6;
  --leading-relaxed: 1.75;

  --tracking-tight: -0.02em;
  --tracking-normal: 0;
  --tracking-wide: 0.04em;
  --tracking-wider: 0.09em;

  /* ---- Spacing (4px base) ---------------------------------------------- */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  /* Vertical rhythm between page sections, tighter on small screens. */
  --section-gap: clamp(2.5rem, 1.6rem + 4vw, 5rem);

  /* ---- Radii ----------------------------------------------------------- */
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-2xl: 28px;
  --radius-pill: 999px;

  /* ---- Elevation ------------------------------------------------------- */
  --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.04);
  --shadow-lg: 0 12px 28px rgba(15, 23, 42, 0.1), 0 4px 8px rgba(15, 23, 42, 0.05);
  --shadow-xl: 0 24px 48px rgba(15, 23, 42, 0.14), 0 8px 16px rgba(15, 23, 42, 0.06);
  --shadow-brand: 0 8px 24px rgba(18, 131, 108, 0.22);

  /* ---- Motion ---------------------------------------------------------- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --duration-fast: 140ms;
  --duration-base: 220ms;
  --duration-slow: 380ms;

  /* ---- Layout ---------------------------------------------------------- */
  --container-max: 1320px;
  --container-pad: clamp(1rem, 0.6rem + 1.8vw, 2rem);
  --header-height: 72px;
  --announcement-height: 40px;

  /* The header is a single row: brand, navigation, search and account controls
     share it. --header-offset is the full height anything sticky must clear and
     is kept as its own name so call sites need not change if a second row ever
     returns. */
  --nav-height: 0px;
  --header-offset: calc(var(--header-height) + var(--nav-height));

  /* Height of the mobile buy bar (12px padding + 56px thumbnail + 12px), so
     floating controls can sit clear of it rather than on top of "Add to bag". */
  --buy-bar-height: 80px;

  /* iOS home indicator and notch. Zero everywhere else. */
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  /* ---- Z-index scale --------------------------------------------------- */
  --z-sticky: 100;
  --z-header: 200;
  --z-dropdown: 300;
  --z-drawer: 400;
  --z-modal: 500;
  --z-toast: 600;
}

/* ==========================================================================
   Reset
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;

  /* Anchored sections must clear the sticky header. */
  scroll-padding-top: calc(var(--header-offset) + var(--space-4));

  /* A last-resort guard against sideways scroll on narrow screens. `clip`
     rather than `hidden` because `hidden` would turn this into a scroll
     container and silently break every `position: sticky` inside it. */
  overflow-x: clip;
}

body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--text-primary);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1, "liga" 1, "cv11" 1;

  /* Keeps the footer at the bottom on short pages. `svh` measures the viewport
     with the mobile browser chrome expanded, so the page never gains a stray
     scrollbar the moment the address bar reappears. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* Scroll is locked while a drawer, modal or the boot overlay owns the screen.
   Applied to <html> so iOS honours it. */
html[data-scroll-locked="true"] {
  overflow: hidden;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

p,
h1,
h2,
h3,
h4,
h5,
h6 {
  overflow-wrap: break-word;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  font-weight: 650;
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
  padding: 0;
}

a {
  color: var(--text-link);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-out);
}

a:hover {
  color: var(--brand-800);
}

/* A visible focus ring is required for keyboard accessibility; :focus-visible
   keeps it from appearing on mouse clicks. */
:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

::selection {
  background: var(--brand-200);
  color: var(--brand-900);
}

/* Respect a reader who has asked the operating system for less motion. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.container--narrow {
  max-width: 820px;
}

.container--wide {
  max-width: 1560px;
}

.section {
  padding-block: var(--section-gap);
}

.section--tight {
  padding-block: calc(var(--section-gap) * 0.6);
}

.section--sunken {
  background: var(--surface-sunken);
}

.stack > * + * {
  margin-block-start: var(--flow-gap, var(--space-4));
}

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

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

/* Product grids collapse predictably: 2 columns on phones is the density
   customers expect, so it never drops to 1. */
.grid--products {
  grid-template-columns: repeat(var(--cols-mobile, 2), minmax(0, 1fr));
}

@media (min-width: 640px) {
  .grid--products {
    grid-template-columns: repeat(var(--cols-tablet, 3), minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .grid--products {
    grid-template-columns: repeat(var(--cols-desktop, 4), minmax(0, 1fr));
  }
}

/* `min(--min-col, 100%)` rather than the bare value: a hard floor wider than
   the container (a 320px card in a 288px column on a small phone) forces the
   track to that width and pushes the page sideways. */
.grid--auto {
  grid-template-columns: repeat(auto-fill, minmax(min(var(--min-col, 240px), 100%), 1fr));
}

/* ==========================================================================
   Typography helpers
   ========================================================================== */

.display {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
}

.text-2xs { font-size: var(--text-2xs); }
.text-xs { font-size: var(--text-xs); }
.text-sm { font-size: var(--text-sm); }
.text-md { font-size: var(--text-md); }
.text-lg { font-size: var(--text-lg); }
.text-xl { font-size: var(--text-xl); }
.text-2xl { font-size: var(--text-2xl); }
.text-3xl { font-size: var(--text-3xl); }
.text-4xl { font-size: var(--text-4xl); }

.text-muted { color: var(--text-muted); }
.text-secondary { color: var(--text-secondary); }
.text-brand { color: var(--brand-700); }
.text-danger { color: var(--danger-600); }
.text-success { color: var(--success-700); }

.font-medium { font-weight: 500; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }

.uppercase-label {
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: var(--text-2xs);
  font-weight: 650;
}

/* Clamps a paragraph to a fixed number of lines so cards stay the same height. */
.line-clamp-1,
.line-clamp-2,
.line-clamp-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.line-clamp-1 { -webkit-line-clamp: 1; }
.line-clamp-2 { -webkit-line-clamp: 2; }
.line-clamp-3 { -webkit-line-clamp: 3; }

/* ==========================================================================
   Accessibility utilities
   ========================================================================== */

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* An absolutely positioned descendant is only clipped by an `overflow`
   ancestor that is itself positioned. Without this, the screen-reader-only
   labels inside a wide, horizontally scrolling table escape the scroller and
   drag the whole page sideways. */
.table-wrap,
.admin-table-wrap,
.scroller,
.tabs,
.gallery__thumbs {
  position: relative;
}

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  z-index: var(--z-toast);
  padding: var(--space-3) var(--space-5);
  background: var(--brand-700);
  color: var(--text-inverse);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  font-weight: 600;
  transition: top var(--duration-base) var(--ease-out);
}

.skip-link:focus {
  top: 0;
  color: var(--text-inverse);
}

/* ==========================================================================
   Print — used by invoices and order receipts
   ========================================================================== */

@media print {
  .no-print,
  .site-header,
  .site-footer,
  .floating-actions,
  .announcement-bar {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #555;
  }

  .page-break {
    page-break-after: always;
  }
}
