/* Public-site theme on top of Bootstrap. Bootstrap loads first; this file and
   the per-feature sheets (cms.css) carry only what Bootstrap doesn't provide.
   Color-mode aware: the layout sets data-bs-theme from the OS preference, so
   use --bs-* variables here instead of hard-coded colors. */

/* Brand: --brand* variables are emitted inline by BrandCssHelper from the
   workspace_brand_color config; per-client overrides live in /assets/brand/brand.css.
   Fallbacks are Bootstrap's stock blue so an unbranded instance still looks sane. */
/* Type scale below Bootstrap's floor.
   Bootstrap 5.3 ships .fs-1 .. .fs-6 and stops. The admin theme (style.bundle.css)
   continues the scale to .fs-7/8/9, and base markup was written against THAT scale —
   135 uses across the frontend templates and CMS blocks: SKU lines, cart variant
   names, blog card dates, "only N left" hints, invoice numbers under order numbers.
   The frontend never loads the admin bundle, so all 135 silently rendered at full
   16px body size and the hierarchy below .fs-6 simply did not exist. It fails
   invisibly — nothing errors, the text is merely too large — which is why it survived
   to a client noticing "inconsistent sizes".
   Values are the admin theme's, not new ones, so the platform has ONE type scale.
   !important matches how Bootstrap emits its own .fs-* utilities, so these behave
   predictably against the utilities they sit beside. */
.fs-7 { font-size: 0.95rem !important; }
.fs-8 { font-size: 0.85rem !important; }
.fs-9 { font-size: 0.75rem !important; }

:root { --bs-primary: var(--brand, #0d6efd); --bs-primary-rgb: var(--brand-rgb, 13, 110, 253); --bs-link-color: var(--brand, #0d6efd); --bs-link-hover-color: var(--brand-active, #0a58ca); }
.btn-primary { --bs-btn-bg: var(--brand, #0d6efd); --bs-btn-border-color: var(--brand, #0d6efd); --bs-btn-hover-bg: var(--brand-hover, #0b5ed7); --bs-btn-hover-border-color: var(--brand-hover, #0b5ed7); --bs-btn-active-bg: var(--brand-active, #0a58ca); --bs-btn-active-border-color: var(--brand-active, #0a58ca); --bs-btn-disabled-bg: var(--brand, #0d6efd); --bs-btn-disabled-border-color: var(--brand, #0d6efd); }

.site-header { border-bottom: 1px solid var(--bs-border-color); }
/* Keep the nav away from the viewport edges (per the key visual) and stop
   menu labels breaking into two lines. */
.site-header__inner { padding-inline: clamp(20px, 5vw, 96px); }
.site-header .nav-link { white-space: nowrap; }

/* Transparent gradient header laid over a hero banner (pages starting with one). */
body.cms-hero-first main { padding: 0; }
.site-header .navbar { padding-top: .85rem; padding-bottom: .85rem; }
/* Fixed from the very first pixel — switching absolute→fixed mid-scroll caused a visible jump. */
.site-header--overlay { position: fixed; top: 0; left: 0; right: 0; z-index: 100; border-bottom: 0;
	background: linear-gradient(180deg, rgba(0,0,0,.72) 0%, rgba(0,0,0,.35) 55%, rgba(0,0,0,0) 100%);
	transition: transform .3s ease; }
/* A gradient can't animate into a solid color — fade a solid layer in instead. */
.site-header--overlay::before { content: ""; position: absolute; inset: 0; z-index: -2;
	background: rgba(10, 10, 14, .94); opacity: 0; transition: opacity .35s ease; }
.site-header--overlay .nav-link, .site-header--overlay .navbar-brand { color: #fff; }
.site-header--overlay .nav-link.nav-accent { color: var(--brand-accent, #cfe2ff); }
.site-header--overlay.is-scrolled::before { opacity: 1; }
/* Scroll down past the hero → slide away; any upward scroll brings it back. */
.site-header--overlay.is-hidden { transform: translateY(-100%); }
/* Mobile: the menu expands down from the top as a full-width dark panel. */
@media (max-width: 991.98px) {
	.site-header--overlay .navbar-collapse { position: fixed; top: 0; left: 0; right: 0; z-index: -1;
		background: rgba(12, 12, 16, .97); padding: 104px 28px 40px; max-height: 100dvh; overflow-y: auto; }
	.site-header--overlay .navbar-collapse .nav-link { font-size: 1.4rem; font-weight: 600; padding: 16px 0;
		border-bottom: 1px solid rgba(255,255,255,.12); }
	.site-header--overlay .navbar-collapse .nav-item:last-child .nav-link { border-bottom: 0; }
	.site-header--overlay .navbar-collapse .dropdown-menu { position: static; background: transparent;
		border: 0; padding: 0 0 6px 14px; margin: 0; }
	.site-header--overlay .navbar-collapse .dropdown-item { color: #e8eaee; font-size: 1.05rem; padding: 10px 0; }
	.site-header--overlay .navbar-collapse .dropdown-item:hover { background: transparent; color: var(--brand-accent, #cfe2ff); }
}
.navbar-brand { font-weight: 700; display: flex; align-items: center; gap: 10px; }
.navbar-brand img { height: 36px; width: auto; display: block; }
.site-header .nav-link { font-weight: 500; }
.site-header .nav-link.nav-accent { color: var(--bs-primary); font-weight: 600; }

main { min-height: 60vh; padding: 48px 0; }

.site-footer { border-top: 1px solid var(--bs-border-color); color: var(--bs-secondary-color); font-size: 14px;
	background: var(--bs-tertiary-bg); }
.site-footer a { color: inherit; }
.site-footer__bar { background: var(--brand-footer-bg, #3d444b); color: #e2e6ea; }

/* Branded circular social icons (footer) */
.soc { width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center;
	justify-content: center; color: #fff !important; font-size: 18px; text-decoration: none; }
.soc:hover { filter: brightness(1.1); }
.soc--ig { background: radial-gradient(circle at 30% 110%, #fdf497 0%, #fd5949 45%, #d6249f 60%, #285aeb 90%); }
.soc--fb { background: #1877f2; }
.soc--yt { background: #ff0000; }
.soc--li { background: #0a66c2; }

/* Floating helpers (bottom-right stack). */
.float-wa, .float-top { position: fixed; right: 22px; z-index: 90; display: flex; flex-direction: column;
	align-items: center; justify-content: center; border-radius: 50%; box-shadow: 0 8px 22px rgba(0,0,0,.25); }
.float-wa { bottom: 96px; width: 52px; height: 52px; background: #25d366; }
.float-top { bottom: 26px; width: 52px; height: 52px; background: #3d4249; color: #fff;
	border: 0; opacity: 0; pointer-events: none; transition: opacity .2s, background .15s; }
.float-top:hover { background: #52585f; }
.float-top.is-visible { opacity: 1; pointer-events: auto; }

/* ── Auth / account pages (everything else on them is Bootstrap) ── */
.auth-box { max-width: 420px; margin: 24px auto; }
.auth-box--wide { max-width: 560px; }
/* A body laid out as a grid (the profile page's two columns) takes the whole container. */
.auth-box--grid { max-width: none; margin: 24px 0; }
.auth-sep { display: flex; align-items: center; gap: 10px; color: var(--bs-secondary-color);
	font-size: 12px; text-transform: uppercase; letter-spacing: .06em; margin: 22px 0 16px; }
.auth-sep::before, .auth-sep::after { content: ""; flex: 1; border-top: 1px solid var(--bs-border-color); }
.otp-input { text-align: center; letter-spacing: 10px; font-size: 22px; }

/* ---- intl-tel-input (.js-phone) ------------------------------------------------
   The vendor wraps the field in `.iti { display: inline-block }`. Bootstrap's
   .form-label is inline-block too, so without this the label sits BESIDE the input
   instead of above it, and .form-control's width:100% resolves against a wrapper
   that shrank to its content. Making the wrapper behave like the form-control it
   replaced restores the normal stacked field. Applies wherever .js-phone is used;
   the CMS enquiry form has carried its own scoped copy since before the convention. */
.iti { display: block; width: 100%; }
.iti > .form-control { width: 100%; }

/* Searchable selects (select.js-search → Select2). The box carries .form-select, but the
   vendor theme hard-codes Bootstrap 5.0's field metrics (#ced4da, .25rem) and outranks
   the class — so the box is pinned to the same 5.3 tokens every other .form-select on
   the page resolves to. A client restyling .form-select restates it for
   .select2-selection.form-select in brand.css (summerpots does). */
.select2-container--bootstrap-5 .select2-selection.form-select {
	/* Longhands on purpose, so the state rules below can restate the colour alone
	   without re-declaring width and style. */
	border-width: var(--bs-border-width, 1px);
	border-style: solid;
	border-color: var(--bs-border-color, #dee2e6);
	border-radius: var(--bs-border-radius, .375rem);
	background-color: var(--bs-body-bg, #fff);
}
/* The rule above outranks the theme's own state rules, so the two states a field must
   still show are restated: focus exactly as Bootstrap's .form-select:focus, and the
   validator's red border (it marks the hidden <select>, the theme reads the sibling). */
.select2-container--bootstrap-5.select2-container--focus .select2-selection.form-select,
.select2-container--bootstrap-5.select2-container--open .select2-selection.form-select {
	border-color: #86b7fe;
	box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25);
}
.is-invalid + .select2-container--bootstrap-5 .select2-selection.form-select {
	border-color: var(--bs-form-invalid-border-color, #dc3545);
}
.select2-container--bootstrap-5 .select2-dropdown {
	border-color: var(--bs-border-color, #dee2e6);
	border-radius: var(--bs-border-radius, .375rem);
}

/* The dropdown is appended to <body> (so it is never clipped by a card or an
   offcanvas), which puts it outside every Bootstrap stacking context — it needs a
   z-index above the sticky header and the offcanvas backdrop to be clickable. */
.iti--container { z-index: 1080; }

/* ── Storefront chrome (site_header_variant = storefront) ───────────────────────
   STRUCTURE ONLY — the grid, the stacking, the drawer transition. Deliberately no
   colours, no fonts, no borders beyond what layout needs: appearance is the client
   layer's job in brand.css, and every rule here is one a client would otherwise have
   to rewrite before they could restyle anything.
   The classic header is untouched by all of this. */

.site-brandbar__inner { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem; }
.site-brandbar__side { display: flex; align-items: center; gap: .25rem; }
.site-brandbar__side--end { justify-content: flex-end; }
.site-brandbar__logo { justify-self: center; }
.site-brandbar__brand img { max-height: 56px; width: auto; }
/* The footer logo needs its own ceiling: workspace_logo_url is whatever the client
   uploaded, and an unconstrained <img> in a footer column renders at natural size —
   a 1200px mark filled the viewport before this line existed. */
.site-footer__logo img { max-height: 48px; width: auto; }

/* Icon buttons carry no chrome of their own so a client can make them anything. */
.site-iconbtn { display: inline-flex; align-items: center; justify-content: center;
	width: 2.5rem; height: 2.5rem; border: 0; background: none; color: inherit;
	text-decoration: none; line-height: 1; }
.site-iconbtn__badge { position: absolute; top: .15rem; right: .05rem; }

.site-social { gap: .75rem; }
.site-social__link { color: inherit; text-decoration: none; }

.site-nav__list { gap: 1.5rem; flex-wrap: wrap; }
.site-nav__link { color: inherit; text-decoration: none; display: inline-block; padding: .5rem 0; }

/* Drawer: panels stack in the same box and slide. The root sits at rest; a sub-panel
   waits one width to the right. Only .is-active is interactive — an inactive panel
   keeps its links out of the tab order rather than leaving them focusable off-screen. */
.site-drawer__body { position: relative; overflow-x: hidden; padding: 0; }
.site-drawer__panel { position: absolute; inset: 0; overflow-y: auto;
	transform: translateX(100%); visibility: hidden;
	transition: transform .25s ease, visibility .25s ease; }
.site-drawer__panel--root { transform: translateX(-100%); }
.site-drawer__panel.is-active { transform: translateX(0); visibility: visible; }
.site-drawer__link { display: flex; align-items: center; justify-content: space-between;
	width: 100%; gap: .75rem; padding: .85rem 1.25rem; border: 0; background: none;
	color: inherit; text-decoration: none; text-align: inherit; }
.site-drawer__link--back { justify-content: flex-start; }

@media (prefers-reduced-motion: reduce) {
	.site-drawer__panel { transition: none; }
}

/* Product page: what the picked option includes — first, above quantity; the product description below is the copy. */
.prod-option-desc { white-space: pre-line; padding: 10px 14px; border-left: 3px solid var(--bs-primary, #0d6efd); background: rgba(0, 0, 0, .03); border-radius: 0 6px 6px 0; }
/* Category sort: the active choice reads at a glance; wraps on narrow screens */
.shop-sort .btn-group { gap: 0; }
