/* =========================================================================
   dh.css — THE DIVINEHINDU CLONE LAYER (CW-58, 2026-09-05)

   Read docs/DH-CLONE.md before changing anything in this file. It carries the
   measurement table every number here comes from and the thirteen decisions
   the owner took on 2026-09-05, several of which deliberately reverse earlier
   ones.

   ⚠️ THIS FILE IS LOADED LAST, AFTER brand.css. That is the whole point of it
   existing rather than being appended to brand.css:

     1. brand.css is 184KB and re-declares several of these selectors at
        different points in the file. A rule written mid-file loses silently to
        a later re-declaration of the same specificity — that has already cost
        an hour once (§35.2, `.cw-header__inner`). Being in a later FILE means
        equal specificity wins, so the rules here do not have to out-specify
        anything.
     2. The whole pass is reversible by deleting one <link>.

   ⚠️ SPECIFICITY STILL MATTERS AGAINST TAILWIND. Bagisto's markup is Tailwind
   utilities. `.max-md\:hidden` is (0,1,0) and `.cw-body .cw-thing` is (0,2,0),
   so a component rule here BEATS a utility inside a media query — which is a
   bug the repo has already shipped once (§30.4). When the intent is "let
   Bagisto's utility win", do not write a `.cw-body` rule at all.
   ========================================================================= */


/* =========================================================================
   1. THE HEADER — one row, 67px, sticky at ~97px with the announcement

   MEASURED, not chosen. Before this file the phone header was 240px of a
   844px screen — 28% of the viewport, permanently, on every page:

       announcement   37px   (scrolled away)
       header row    158px   (logo row 84 + its own full-width search row 74)
       shortcut row   82px   (sticky, on every page)
       ------------------------------------------------------------
       sticky total  240px

   divinehindu, the reference, runs 97px: a 25px announcement and a 69px row
   holding hamburger · logo · search icon · account · cart. The search is a
   BUTTON there, not a field, which is where most of the difference comes from.

   Target arithmetic for our own row:

       logo    clamp(44px, 13vw, 52px)  ->  50.7px at 390
       padding 8px top + 8px bottom     ->  16px
       ------------------------------------------------
       row                                  ~67px
       announcement                         ~30px
       ------------------------------------------------
       sticky total                         ~97px

   ⚠️ D1 REVERSES A DELIBERATE EARLIER DECISION. brand.css says the
   announcement strip "stays OUTSIDE this wrapper on purpose — pinning it would
   cost 40px of every screen". The owner was shown that trade-off on
   2026-09-05 and chose to match divinehindu, which pins it. It is 30px here,
   not 40, because the padding is trimmed to DH's.
   ========================================================================= */

@media (max-width: 900px) {
	/* The announcement joins the sticky block. `.cw-headwrap` is the sticky
	   element; moving the strip inside it is done in the Blade, this only
	   sizes it. */
	.cw-body .cw-announce {
		padding-block: 6px;
		font-size: .6875rem;
		line-height: 1.4;
	}

	/* ⚠️ ONE ROW, NOT TWO. The `"search search search"` second row defined in
	   brand.css at max-width:700 is what made this header 158px. The search is
	   a toggle button now and lives in the actions cluster, so the row
	   collapses to nav · logo · actions and the grid areas must be redeclared
	   or the browser keeps reserving the empty second row. */
	.cw-body .cw-header__inner {
		grid-template-columns: 1fr auto 1fr;
		grid-template-areas: "nav logo actions";
		align-items: center;
		padding-block: 8px;
		row-gap: 0;
	}

	/* The field is no longer a grid item in this row. It is inside the
	   drop-down panel below, which is a sibling of the header. */
	.cw-body .cw-header .cw-search { display: none; }

	/* ⚠️ 13vw, DOWN FROM 17vw. A 67px row cannot hold an 84px mark. At 390px
	   this is 50.7px, which is what leaves 8px of air above and below inside a
	   67px row. Below 338px the 44px floor takes over and the row grows to
	   60px, which is still inside the target.

	   The mark is 1:1 (CW-48), so max-width is also its height — a non-square
	   replacement changes this row's height. */
	.cw-body .cw-logo img { max-width: clamp(44px, 13vw, 52px); }

	/* 🔴 THREE ICONS ON THE RIGHT, NOT FOUR. THIS IS ARITHMETIC, NOT TASTE.

	   §35.2's constraint for a centred phone logo is

	       track = (viewport - 2*padding - logo) / 2   must be >=  actions

	   At 320px that track is (320 - 24 - 44) / 2 = 126px. The cluster was
	   WhatsApp (already hidden on phones), wishlist, account and cart; adding
	   the search toggle made it FOUR visible icons —

	       4 x 34 + 3 x 4 = 148px

	   — which overflowed by 22px and put the icons ON the centred logo. That is
	   the exact failure `ui:browser` has guarded since CW-55 centred the mark,
	   and it caught this one: "320px: nothing overlaps the logo — icons overlap
	   by 22px". It is also why this rule is here rather than the alternatives:
	   un-centring the logo reverses CW-55, and shrinking the targets to 29px to
	   make four fit trades a real affordance for a redundant one.

	   Three is 110px and clears 126 with 16px to spare; at 390 the track is
	   157px. And three is what the reference does — divinehindu's phone header
	   is hamburger · logo · search · account · cart, with no wishlist. It stays
	   reachable from the account area, as it is on both reference sites.

	   ⚠️ IF YOU ADD A FOURTH ICON HERE, DO THE ARITHMETIC AT 320 FIRST. */
	.cw-body .cw-header__actions .cw-iconlink--wish { display: none; }
}

/* =========================================================================
   2. THE SEARCH TOGGLE AND ITS DROP-DOWN PANEL  (owner request #2, D9)

   divinehindu's header search is a 22px icon button that drops a full-width
   field down from under the header with the page dimmed behind it. This is
   that, with two differences that are deliberate:

     - it is a NATIVE <details>, like the existing mobile nav drawer, for the
       reason stated at the top of header/index.blade.php: the header is the
       worst possible place for a control that dies when a script fails. It
       opens, closes and is keyboard- and screen-reader-operable with every
       line of JavaScript in this theme deleted.
     - the FORM INSIDE IT IS THE SAME REAL GET FORM as before, so with JS off
       it still submits to the search page.

   ⚠️ THE PANEL IS A SIBLING OF `.cw-header`, INSIDE `.cw-headwrap`. Inside the
   header row it would be a grid item and would reopen the second-row problem
   this whole section exists to remove.
   ========================================================================= */

.cw-body .cw-searchtoggle { display: none; }

.cw-body .cw-searchtoggle > summary {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 999px;
	cursor: pointer;
	color: var(--cw-color-ink, #35251D);
	list-style: none;
	transition: background-color .18s ease;
}

/* Safari draws its own triangle unless BOTH of these are cleared. */
.cw-body .cw-searchtoggle > summary::-webkit-details-marker { display: none; }
.cw-body .cw-searchtoggle > summary::marker { content: ""; }

.cw-body .cw-searchtoggle > summary:hover { background: var(--cw-color-gold-soft, #FDF3D8); }

.cw-body .cw-searchtoggle > summary svg {
	width: 22px;
	height: 22px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
}

/* The X replaces the magnifier while the panel is open, which is what tells a
   shopper the same button closes it. */
.cw-body .cw-searchtoggle > summary .cw-searchtoggle__close { display: none; }
.cw-body .cw-searchtoggle[open] > summary .cw-searchtoggle__close { display: block; }
.cw-body .cw-searchtoggle[open] > summary .cw-searchtoggle__open  { display: none; }

/* ---- the panel ----

   ⚠️ THERE IS NO SEPARATE PANEL ELEMENT, AND THE FIRST VERSION OF THIS FILE
   ASSUMED THERE WAS. It shipped `.cw-searchtoggle[open] ~ .cw-searchpanel`,
   a SIBLING selector — which matches nothing, because the toggle lives inside
   `.cw-header__actions` and any panel has to live outside it to span the row.
   Siblings they are not, and a sibling combinator that matches nothing fails
   silently: the button would have toggled a `[open]` attribute and moved not
   one pixel.

   What is actually toggled is `.cw-search` — THE ONE REAL SEARCH FORM, the
   same element the desktop row uses. See the Blade for why there is only one
   of them (the typeahead binds to a single `#cw-search-input`).

   `:has()` is what lets a state on a descendant reach an ancestor's sibling.
   Baseline in every engine since Dec 2023; the @supports block below keeps
   older browsers on the old always-visible field rather than a dead button. */

@media (max-width: 900px) {
	.cw-body .cw-searchtoggle { display: block; }

	/* The header row is the positioning context for the drop-down. Without
	   this the panel would resolve against the sticky wrapper and sit below
	   the department bar and the shortcut row instead of directly under the
	   row that opened it. */
	.cw-body .cw-header { position: relative; }

	.cw-body .cw-header__inner:has(.cw-searchtoggle[open]) .cw-search {
		display: block;
		position: absolute;
		left: 0;
		right: 0;
		top: 100%;
		width: auto;
		max-width: none;
		margin-inline: 0;
		padding: 10px 12px 12px;
		background: var(--cw-color-cream, #FFFAEB);
		border-bottom: 1px solid var(--cw-color-line, #E8DCC8);
		box-shadow: 0 10px 24px rgba(53, 37, 29, .12);
		/* Above the scrim below, which is the summary's own ::after. */
		z-index: 3;
	}

	/* ⚠️ THE SUBMIT BUTTON NEEDS AN EXPLICIT VERTICAL POSITION HERE, and
	   leaving it out shipped the magnifier hanging BELOW the field, half
	   outside the panel.

	   components.css gives it `position: absolute; right: .3rem` and NO `top`.
	   An absolutely positioned box with `top: auto` sits at its STATIC
	   position — where it would have been in normal flow — which is on the
	   line after the input, not on top of it. In the header row that never
	   showed, because the form is a stretched grid item exactly as tall as the
	   input, so "the line after" and "beside it" are the same place. Give the
	   form 10px of padding and they stop being the same place.

	   `top` + `bottom` + `margin-block: auto` centres it against the padding
	   box without needing to know the input's height. */
	.cw-body .cw-header__inner:has(.cw-searchtoggle[open]) .cw-search button {
		top: 10px;
		bottom: 12px;
		margin-block: auto;
		/* ⚠️ AND THE HORIZONTAL OFFSET HAS TO GROW BY THE PANEL'S PADDING TOO.
		   components.css sets `right: .3rem`, brand.css `right: .35rem` — both
		   resolved against the form's PADDING BOX, which is the full 390px of
		   the panel. The input sits inside the CONTENT box, 12px narrower on
		   each side, so the magnifier hung 6px past the field's right edge and
		   over the panel's own padding.

		   Visually it reads as "nearly right", which is why the check measures
		   the button against the INPUT rather than eyeballing a screenshot. */
		right: calc(12px + .35rem);
	}

	/* ⚠️ THE SCRIM IS DRAWN BY THE SUMMARY, NOT BY A SEPARATE ELEMENT — the
	   same trick the mobile nav drawer already uses. A tap anywhere on the
	   dimmed page lands on the summary and toggles the <details> shut, with no
	   JavaScript and no click-outside handler.

	   ⚠️ IT IS `position: absolute` AGAINST `.cw-header`, NOT `position: fixed`
	   WITH A `top` OFFSET, and the offset version was written first.

	   At `inset: 0` a fixed scrim covers the field itself and every tap meant
	   for the input closes the panel instead. The obvious repair is
	   `top: <height of the header block>` — but that height is not a constant
	   and cannot be written down: `.cw-scrolled` shrinks the logo, and the
	   block is 95px on a category page against 177px on the homepage, where
	   the shortcut row is inside the same wrapper. A literal is wrong on at
	   least one of those pages and drifts on all of them.

	   `top: 100%` of `.cw-header` is that number, computed by the browser,
	   whatever it happens to be. The panel above is positioned the same way and
	   carries the higher z-index, so it paints over the first 72px of the
	   scrim; everything below the header row dims, including the shortcut row
	   on the homepage, which is correct — that row is page content.

	   `100vh` rather than `bottom: 0`: the scrim's containing block is the
	   header row, which is ~67px tall, so a percentage height would resolve
	   against that and dim 67 pixels of the page. */
	.cw-body .cw-searchtoggle[open] > summary::after {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		top: 100%;
		height: 100vh;
		background: rgba(53, 37, 29, .45);
		z-index: 1;
	}

	/* ⚠️ NO `:has()`, NO TOGGLE. An engine that cannot match the rule above
	   would render a button that does nothing and no way to search at all —
	   which is worse than the header we started with. Here the field simply
	   stays where it was, on its own second row, and the button is hidden. */
	@supports not selector(:has(*)) {
		.cw-body .cw-searchtoggle { display: none; }

		.cw-body .cw-header__inner {
			grid-template-areas:
				"nav logo actions"
				"search search search";
		}

		.cw-body .cw-header .cw-search {
			display: block;
			grid-area: search;
			max-width: none;
			margin-inline: 0;
		}
	}
}

/* =========================================================================
   3. THE SHORTCUT ROW — homepage only  (D8)

   Best Seller · New Arrivals · Sacred Collection · Festive Picks. 82px, and
   until now it rendered inside the sticky wrapper on EVERY page, so a category
   page paid for it twice: once in the scroll and once in the pinned height.

   divinehindu shows the equivalent row on its homepage only. The Blade guard
   in header/index.blade.php is the whole implementation.

   ⚠️ THERE IS NO CSS BELT HERE ON PURPOSE, AND THE OBVIOUS ONE IS A BUG.
   `.cw-body:not(.cw-home) .cw-shortcuts { display: none }` was written here and
   removed the same day: NO `.cw-home` CLASS EXISTS on the body, so `:not()`
   matches the homepage too and the rule hid the row on every page including
   the one page it is supposed to appear on. If you want a belt, add the body
   class first, then prove the rule works by deleting the Blade guard.
   ========================================================================= */

/* =========================================================================
   4. THE CATEGORY HEAD — title + Filters on one row  (owner request #4, D4)

   Was: breadcrumb (17px) + H1 (40px) + a four-line blurb (96px) inside a band
   with 48px of vertical padding = 260px, before a 99px filter bar, before the
   grid. First product at y=732 on a 844px screen: a shopper landing on a
   category page saw no product at all without scrolling.

   Now: one 56px row carrying the category name and the Filters control, and
   the grid immediately under it. divinehindu carries no breadcrumb anywhere on
   its site and no category description on its collection pages.

   ⚠️ THE BLURB IS REMOVED FROM THE PAGE, NOT DELETED FROM THE DATABASE. The
   description still lives on the category record, is still in the <meta>
   description, and can be put back by deleting one rule. The owner declined
   moving it below the grid.
   ========================================================================= */

.cw-body .cw-cathead__crumbs,
.cw-body .cw-cathead__blurb { display: none; }

/* ⚠️ THE PADDING AND MARGIN ARE THE POINT, not the background. elevation.css
   :524 gives this band `padding: var(--cw-space-40) var(--cw-space-30)` and
   `margin-bottom: var(--cw-space-40)` — 48px above the title, 48px below it and
   another 40px of margin under the band, which is 136px of air around one line
   of text. Clearing only `background` and `border` left the band at 131px and
   looked like the rule had not worked at all.

   The horizontal padding is deliberately NOT touched: it is the content frame
   (§24.2) and the filter bar below lines up with it. */
.cw-body .cw-cathead {
	background: transparent;
	border: 0;
	padding-block: 10px;
	margin-bottom: 0;
}

.cw-body .cw-cathead__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding-block: 14px;
	min-height: 0;
}

.cw-body .cw-cathead__title {
	margin: 0;
	font-size: clamp(1.25rem, 5vw, 1.75rem);
	line-height: 1.15;
}

/* The count divinehindu shows on the right of the same row ("51 Products").
   Rendered by the Blade only when the page actually knows the number. */
.cw-body .cw-cathead__count {
	margin: 0;
	flex: 0 0 auto;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--cw-color-maroon, #6C1322);
	white-space: nowrap;
}

/* ---- the filter bar: ONE row on a phone, not three ----

   ⚠️ WHY THE `<h1>` IS NOT IN THIS ROW, which is what D4's sketch showed.

   The Filters button lives inside `#v-category-template`, a
   `<script type="text/x-template">` that Vue compiles after mount. The `<h1>`
   is server-rendered in `.cw-cathead`, OUTSIDE the `<v-category>` element and
   therefore outside that component's scope. Moving the heading into the
   template would put the page's only H1 inside a <script> tag — absent from
   the served HTML — and moving the button out of it would cut it off from
   `cwFiltersOpen`, the state that opens the panel. Neither is worth 37px.

   So the title keeps its own row and this row is compressed instead: it was
   `flex-direction: column` — a full-width toggle stacked over the tools, 99px
   — and it is now a single 44px line. The measured result is what D4 actually
   asked for: 95px of header + 50px title + 44px controls + 24px count = the
   first product at y=213, against y=732 before.

   ⚠️ THIS OVERRIDES `flex-direction: column` FROM brand.css:4541. Same
   specificity, later file — which is the entire reason dh.css exists. */
@media (max-width: 767px) {
	.cw-body .cw-filterbar {
		flex-direction: row;
		align-items: center;
		flex-wrap: nowrap;
		gap: 8px;
		margin-top: 0;
	}

	.cw-body .cw-filterbar__toggle {
		width: auto;
		flex: 0 0 auto;
		padding: .5rem .75rem;
		font-size: .8125rem;
		gap: .375rem;
	}

	.cw-body .cw-filterbar__tools {
		flex: 1 1 auto;
		min-width: 0;
		width: auto;
	}

	/* ⚠️ THE GRID/LIST MODE SWITCHER IS HIDDEN ON PHONES, and that is a clone
	   decision rather than a space one: neither divinehindu nor
	   certifiedcrystal offers a list mode on mobile at all. It also buys the
	   ~60px that lets the rest of the row fit — the arithmetic at 390px is
	   358px of usable width against Filters 100 + sort 110 + limit 70 +
	   switcher 60 + gaps 24 = 364, which does not.

	   ⚠️ SELECTED BY WHAT IT CONTAINS, not by its position. The switcher is an
	   anonymous `<div class="flex items-center gap-5">` inside another
	   anonymous flex div; a positional selector would silently start hiding
	   the wrong element the first time Bagisto reorders that row. The icon
	   class is Vue-bound and swaps between `icon-grid-view` and
	   `icon-grid-view-fill`, so the prefix match is the stable part.

	   The grid mode stays the default, so nothing is lost but the choice. */
	.cw-body .cw-filterbar__tools .flex:has(> [class*="icon-grid-view"]) {
		display: none;
	}
}

/* =========================================================================
   5. 🔴 THE SORT / LIMIT TOOLBAR — owner request #5, "moving out of its bubble"

   THE BUG, MEASURED at 390px before the fix:

       sort button box   x = 24 .. 134   (110px wide)
       its label text            ~155px  ("Price: high to low")
       its chevron       x = 179 .. 203  — 45px OUTSIDE its own box
       the "12" pill     x = 148 ..      — the chevron lands ON it

   THE ROOT CAUSE IS TWO BUGS STACKED.

   ONE: this is Bagisto's DESKTOP toolbar, rendering on a phone. Its markup
   ships two branches, `max-md:hidden` for desktop and a bare unstyled <ul> for
   the mobile drawer we deleted. A `.cw-body` component rule is (0,2,0) and
   `.max-md\:hidden` is (0,1,0), so the desktop branch wins inside the media
   query and shows — §30.4, and it is deliberate: the mobile branch is 255px of
   unstyled plain text.

   TWO: that desktop branch hard-codes `max-md:w-[110px]` on a flex row with
   `justify-between` and NO minimum-width reset on the label. A flex item's
   automatic minimum size is its content, so a 155px text node cannot shrink
   into a 110px box — it overflows, and `justify-between` pushes the chevron
   out past the edge with it.

   ⚠️ THE FIX IS TRUNCATION, NOT A WIDER BOX. The labels vary from "A - Z" to
   "Price: high to low"; any fixed width wide enough for the longest wastes the
   row for the rest, and there are two of these controls side by side in 342px.
   `min-width: 0` is what actually permits the shrink; `overflow: hidden` and
   the ellipsis are what make the result readable.
   ========================================================================= */

@media (max-width: 767px) {
	/* Give the two controls a real share of the row instead of a hard 110px. */
	.cw-body .cw-filterbar__tools .flex.justify-between {
		gap: 8px;
		align-items: center;
	}

	.cw-body .cw-filterbar__tools button {
		/* Overrides Bagisto's `max-md:w-[110px]`: (0,2,0) beats (0,1,0). */
		width: 100%;
		max-width: none;
		min-width: 0;
		gap: 4px;
		padding-inline: 10px;
		/* THE BUBBLE. It had `max-md:border-0`, so the rounded box the owner
		   describes the text escaping from was actually the wrapper behind it,
		   and the button had no visible edge of its own at all. */
		border: 1px solid var(--cw-color-line, #E8DCC8);
		border-radius: 999px;
		background: #FFF;
		/* The label is a bare text node, so it cannot be targeted directly.
		   Truncating on the flex CONTAINER works because the text node is the
		   only in-flow content besides the chevron. */
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		font-size: .8125rem;
	}

	/* ⚠️ THE CHEVRON MUST NOT SHRINK. Without this it is the flex item that
	   gives way once the label is allowed to shrink, and it collapses to 0
	   width — trading a chevron outside the box for no chevron at all. */
	.cw-body .cw-filterbar__tools button > span[class*="icon-"] {
		flex: 0 0 auto;
		font-size: 1.125rem;
	}

	/* The two dropdown wrappers share the row evenly rather than sitting at a
	   fixed 110px each with a 40px gap between them. */
	.cw-body .cw-filterbar__tools .relative { min-width: 0; }
	.cw-body .cw-filterbar__tools .flex.items-center.gap-10 { gap: 8px; min-width: 0; }
}

/* =========================================================================
   6. THE PRODUCT GRID — 180 / 12 / 8  (owner request #6, D5)

   divinehindu's collection grid at 390px: 8px of page padding, two 180px
   cards, 12px between them. 8 + 180 + 12 + 180 + 8 = 388. Ours was 24px of
   padding, two 160px cards and a 21.6px gap — 40px of the screen spent on
   margins that could be photograph.

   ⚠️ THIS IS SCOPED TO THE PRODUCT GRID, NOT TO `.container`. Dropping the
   page frame to 8px everywhere would put body copy against the screen edge and
   break the one-content-frame rule (§24.2). Only the grid goes wide.
   ========================================================================= */

@media (max-width: 767px) {
	/* ⚠️ `margin-inline`, NOT `padding-inline`. The grid sits inside a padded
	   container, so padding here would have ADDED to that padding and produced
	   wider margins than we started with — the exact opposite of the request.
	   The grid has to break OUT of the container.

	   ⚠️ AND THE CONTAINER'S PADDING IS 24px, NOT THE 16px ITS OWN
	   `max-md:px-4` CLASS ADVERTISES. The content frame (§24.2) re-declares it.
	   The first version of this rule trusted the class name, used -8px, and
	   landed the grid at x=16 with 168px cards — wider than before, but not the
	   180px asked for. MEASURE THE PARENT, do not read its class list.

	   Arithmetic at 390px, measured:

	       parent content       342, starting at x=24
	       margin-inline -16px  -> box x=8 .. x=382 = 374 wide
	       two columns          (374 - 12) / 2      = 181px each

	   181px against divinehindu's 180px, and against the 160px this rendered
	   before.

	   ⚠️ THE SELECTOR IS LONGER THAN IT LOOKS LIKE IT NEEDS TO BE, AND
	   `!important` ALONE WAS NOT ENOUGH. elevation.css:902 is

	       .cw-body main .grid.grid-cols-3 { gap: 1.35rem !important; }

	   Two importants do not cancel out — specificity still decides between
	   them, and that selector is (0,3,1) against `.cw-body .cw-prodgrid`'s
	   (0,2,0). The first attempt added `!important` and the gap stayed at
	   21.6px, which reads exactly like the file not being loaded.

	   `.cw-body main .cw-prodgrid.grid` is (0,3,1) — EQUAL, and this file is
	   loaded later, so it wins. That elevation rule is right for the desktop
	   grid it was written for, so it is overridden only inside this media
	   query rather than changed at source. */
	.cw-body main .cw-prodgrid.grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px !important;
		margin-inline: -16px;
		padding-inline: 0;
		justify-items: stretch;
	}

	/* ⚠️ `justify-items: center` ON THE GRID IS WHAT KEPT THE CARDS NARROW.
	   Bagisto ships `max-md:justify-items-center`, which shrink-wraps each card
	   to its content width instead of letting it fill its column. Stretching
	   the items is what actually takes the cards from 160px to 180px — the gap
	   and padding changes alone would have left them centred in wider columns
	   with the extra space as dead air inside the grid. */
	.cw-body .cw-prodgrid > * {
		width: 100%;
		max-width: none;
		justify-self: stretch;
	}
}

/* =========================================================================
   7. THE TILE TRUST BADGES  (D6)

   🔴 READ docs/DH-CLONE.md §3 BEFORE CHANGING THE WORDING. The three labels
   contradict CW-13, in which the client stated in writing that there is no
   certification. The owner was shown that by name on 2026-09-05, was offered a
   visually identical row carrying claims we can stand behind, and chose
   divinehindu's wording anyway. It is an explicit owner decision, recorded —
   the same shape as the fabricated MRPs.

   The wording lives in ONE Blade partial so it is one edit to change.
   ========================================================================= */

.cw-body .cw-tilebadges {
	/* 🔴 CW-79 — A CENTRED CLUSTER, NOT THREE EQUAL COLUMNS.
	   This was `grid-template-columns: repeat(3, minmax(0, 1fr))`, which hands
	   each badge a third of the card and spreads them to the far left, the
	   middle and the far right. The owner reported exactly that on 2026-09-10:
	   "right now they are left alligned, center and right aligned".

	   Measured on certifiedcrystal.com's own listing card: `display: flex`,
	   `justify-content: center`, and the three labels spanning 93px inside a
	   92px holder with ~7px between them — a tight group in the middle of the
	   card, which is what the ticket means by "keep the icons near".

	   ⚠️ THE GAP IS BETWEEN THE ITEMS, NOT AROUND THEM. Going back to a grid
	   with a bigger `gap` does not fix it: with `1fr` columns the items still
	   sit at the thirds and only the whitespace inside each third changes. */
	display: flex;
	justify-content: center;
	align-items: flex-start;
	gap: 7px;
	margin: 6px 0 4px;
}

.cw-body .cw-tilebadges__item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	min-width: 0;
}

.cw-body .cw-tilebadges__item svg {
	width: 15px;
	height: 15px;
	fill: none;
	stroke: var(--cw-color-maroon, #6C1322);
	stroke-width: 1.6;
}

.cw-body .cw-tilebadges__label {
	font-size: .5rem;
	line-height: 1.1;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--cw-color-ink-soft, #7A6A5F);
	text-align: center;
	/* The longest label is "ORIGINAL" at this size; the ellipsis is insurance
	   against a future edit rather than something that fires today. */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	max-width: 100%;
}

/* =========================================================================
   8. THE CATEGORY RAIL  (owner request #7 — D10, D11, D12)

   certifiedcrystal.com's mobile collection page, measured at 390x844:

       header                     64px, sticky
       group tab strip            45px, sticky at top:72
       icon rail          w-[72px],     sticky at top:118, scrolls internally
                                        (2,670px of content in a 704px window)
       content column            318px
       bottom nav                 65px, fixed

   Ours is the same furniture arranged as a drawer, because a permanent 72px
   column and a 180px card cannot both exist at 390px — see the header of
   categories/cw-rail.blade.php for that arithmetic and the owner's choice.

   ⚠️ NO JAVASCRIPT OPENS THIS, SWITCHES ITS TABS OR CLOSES IT. A <details> for
   the drawer, radio inputs for the tabs, and the summary's own ::after for the
   scrim. Same discipline as the header drawer and the search panel.
   ========================================================================= */

/* ---- it is the drawer's CONTENT now, not a drawer ----

   ⚠️ CW-58 D20 MOVED THIS INSIDE `.cw-mobnav__panel`. It used to be its own
   `<details>` with its own toggle button, its own fixed panel and its own
   scrim, opened from a "Categories" button beside the category title. The owner
   asked for the hamburger to open it instead, so all of that is gone: the
   drawer, the scrim, the open/close behaviour and the keyboard handling all
   belong to `.cw-mobnav`, which has been carrying them since CW-51.

   What is left here is the inside of that panel. `.cw-rail__panel` keeps its
   class because `:has(#cw-rail-gN:checked)` below is scoped to it — but it is
   a plain block, and every positioning property it had is explicitly cleared
   rather than deleted, because a stale `position: fixed` inside a panel that is
   ALSO fixed is the kind of thing that renders fine until the drawer scrolls. */

.cw-body .cw-rail { min-width: 0; }

.cw-body .cw-rail__panel {
	position: static;
	inset: auto;
	width: auto;
	z-index: auto;
	display: block;
	background: none;
	border: 0;
	box-shadow: none;
	/* The drawer's own padding is 4.25rem 1.25rem 2rem; the rail spans the full
	   width of it, so the horizontal padding is cancelled and reapplied per
	   element below. */
	margin-inline: -1.25rem;
}

/* ---- the group tabs (D12: inside the drawer, above the rail) ---- */

/* ⚠️ STICKY, NOT FIXED. The tabs must stay reachable while the icon list
   scrolls, and the thing that scrolls is now the DRAWER, not a box inside the
   rail. `position: sticky` against that scroller does it with no measurement;
   the old flex-header arrangement relied on the rail owning its own height,
   which it no longer does. */
.cw-body .cw-rail__tabs {
	display: flex;
	gap: 6px;
	position: sticky;
	top: -4.25rem;
	z-index: 2;
	padding: 14px 12px 10px;
	overflow-x: auto;
	background: var(--cw-color-ground-alt, #FBF3E2);
	border-bottom: 1px solid var(--cw-color-line, #E8DCC8);
	/* Eight groups do not fit across 330px; the strip scrolls sideways, as
	   certifiedcrystal's own does. */
	scrollbar-width: none;
}

.cw-body .cw-rail__tabs::-webkit-scrollbar { display: none; }

.cw-body .cw-rail__tab {
	flex: 0 0 auto;
	padding: .4rem .7rem;
	border: 1px solid var(--cw-color-line, #E7D9C4);
	border-radius: 999px;
	background: #FFF;
	color: var(--cw-color-ink, #35251D);
	font-size: .75rem;
	font-weight: 600;
	line-height: 1;
	white-space: nowrap;
	cursor: pointer;
}

/* ---- the lists ----

   ⚠️ ONE RULE SWITCHES THE GROUPS, and that is why the radio inputs sit next
   to their lists rather than up in the tab strip beside their labels. The
   obvious markup — labels and inputs together — forces one CSS rule PER GROUP
   (`#cw-rail-g0:checked ~ … [data-g="0"]`, and again for 1, 2, 3 …), which
   silently stops covering the last groups the moment the menu grows. Adjacency
   makes it index-free. */

.cw-body .cw-rail__lists {
	flex: 1 1 auto;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	padding: 8px 0 24px;
}

.cw-body .cw-rail__radio {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.cw-body .cw-rail__list { display: none; }
.cw-body .cw-rail__radio:checked + .cw-rail__list { display: block; }

/* ⚠️ THE ACTIVE TAB'S HIGHLIGHT IS THE ONE THING THAT DOES COST A RULE PER
   GROUP, because a <label> cannot see the state of an input it is not next to.
   Ten are written; NavigationComposer currently returns eight groups and drops
   any that end up empty, so there are two spare. If a ninth and tenth ever
   appear they are covered; an eleventh would open correctly and simply not
   light its tab, which is a cosmetic failure rather than a broken control. */
/* ⚠️ THE ACTIVE TAB COSTS A RULE PER GROUP, because a <label> cannot see the
   state of an input it is not adjacent to.

   ⚠️ AND THEY ARE KEYED ON `data-g`, NOT ON THE ID. D26 put a SECOND copy of
   this rail on every category and search page — the permanent sidebar beside
   the drawer's — so ids are now namespaced per instance
   (`cw-rail-side-g0`, `cw-rail-drawer-g0`). Rules naming the old bare ids
   would have lit the tab in one copy and not the other, and would break again
   the next time an instance is added. `data-g` is the same on both.

   Ten are written; NavigationComposer returns eight groups and drops empty
   ones, so there are two spare. An eleventh would open correctly and simply
   not light its tab — cosmetic, not broken. */
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="0"]:checked) .cw-rail__tab[data-g="0"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="1"]:checked) .cw-rail__tab[data-g="1"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="2"]:checked) .cw-rail__tab[data-g="2"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="3"]:checked) .cw-rail__tab[data-g="3"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="4"]:checked) .cw-rail__tab[data-g="4"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="5"]:checked) .cw-rail__tab[data-g="5"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="6"]:checked) .cw-rail__tab[data-g="6"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="7"]:checked) .cw-rail__tab[data-g="7"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="8"]:checked) .cw-rail__tab[data-g="8"],
.cw-body .cw-rail__panel:has(.cw-rail__radio[data-g="9"]:checked) .cw-rail__tab[data-g="9"] {
	background: var(--cw-color-maroon, #6C1322);
	border-color: var(--cw-color-maroon, #6C1322);
	color: #FFF;
}

/* ---- one category ---- */

.cw-body .cw-rail__item {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px 14px;
	color: var(--cw-color-ink, #35251D);
	text-decoration: none;
	font-size: .875rem;
	line-height: 1.25;
}

.cw-body .cw-rail__item:hover { background: var(--cw-color-ground-alt, #FBF3E2); }

/* The current category, as certifiedcrystal marks its own. */
.cw-body .cw-rail__item--on {
	background: var(--cw-color-ground-alt, #FBF3E2);
	font-weight: 700;
	box-shadow: inset 3px 0 0 var(--cw-color-maroon, #6C1322);
}

.cw-body .cw-rail__icon {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	border-radius: 999px;
	object-fit: cover;
	background: var(--cw-color-ground-alt, #FBF3E2);
}

/* The twelve zodiac marks are real Unicode glyphs, not photographs — the same
   split MenuIcons makes for the mega menu. The cream disc is what lets a
   photograph and a glyph sit in one column and still read as one system. */
.cw-body .cw-rail__icon--glyph {
	display: grid;
	place-items: center;
	font-size: 1.25rem;
	color: var(--cw-color-maroon, #6C1322);
}

.cw-body .cw-rail__label {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.cw-body .cw-rail__all {
	display: block;
	margin: 10px 14px 0;
	padding-top: 12px;
	border-top: 1px solid var(--cw-color-line, #E8DCC8);
	color: var(--cw-color-maroon, #6C1322);
	font-size: .8125rem;
	font-weight: 700;
	text-decoration: none;
}

/* ⚠️ DESKTOP KEEPS CW-39 — NO SIDEBAR (decision D13). certifiedcrystal turns
   this rail into a permanent 288px column above `md`. Adopting that would
   reverse the full-width grid the client asked for and approved on 2026-09-04,
   so the whole control is a phone and tablet feature and simply is not
   rendered above 900px. */
@media (min-width: 901px) {
	.cw-body .cw-rail { display: none; }
}

/* =========================================================================
   9. DESKTOP  (decision D3 — this pass covers every width, not just phones)

   What is already shared with the phone, because those rules were written
   without a media query: no breadcrumbs anywhere, no category description, the
   compact title band, and the three tile badges. divinehindu carries no
   breadcrumb on any page at any width, so that is the clone behaving.

   What stays as it is, deliberately:

     - THE SEARCH FIELD REMAINS A REAL FIELD ON DESKTOP. divinehindu uses an
       icon here too, but it can afford to: its desktop logo is CENTRED, so the
       row has no void to fill. §22.13 records the owner rejecting a centred
       desktop logo on sight — "Logo should be on left only" — and with the logo
       left and no field, `auto 1fr auto` leaves the 781px of dead space the
       2026-09-03 rebuild existed to remove. Two of the reference's decisions
       depend on each other; taking one without the other undoes a fix.
     - NO CATEGORY RAIL (D13). certifiedcrystal has a permanent 288px desktop
       sidebar. CW-39 removed exactly that at the client's request and they
       approved the full-width grid on 2026-09-04.
     - THE 4-COLUMN GRID and its 21.6px gap are CW-39's and are left alone. The
       180/12/8 numbers are divinehindu's PHONE numbers and are scoped to the
       phone.
   ========================================================================= */

@media (min-width: 768px) {
	/* ⚠️ 70px OF NOTHING BETWEEN THE TITLE AND THE FILTER ROW. `.cw-listing`
	   carries Tailwind's `md:mt-10` (40px), which was correct when a 260px
	   category band sat above it and needed separating from the controls. With
	   that band cut to one compact line the two belong together, the way
	   divinehindu sets its own title and Filters on a single band.

	   `.cw-body .cw-listing` is (0,2,0) against `.md\:mt-10`'s (0,1,0), so this
	   needs no `!important` — see the note at the top of this file. */
	.cw-body .cw-listing { margin-top: 14px; }
}

/* =========================================================================
   10. scroll-padding-top — RECALIBRATED, because §1 changed the header

   ⚠️ A STICKY HEADER SWALLOWS WHATEVER YOU SCROLL TO. The platform's own
   "N Ratings" control calls `scrollIntoView({block: 'start'})`, which parks the
   target at viewport top — underneath the pinned block. `scroll-padding-top` on
   the scroll container is the fix, and it is INVISIBLE until somebody uses one
   of those controls, which is why it has its own check.

   brand.css set 178 / 130 / 190 for the old header. CW-58 moved the
   announcement strip INTO the sticky wrapper (D1) and took the search row out
   of it, so all three are wrong in both directions — `ui:browser` caught it as
   "scrolling to an element clears the sticky header {gap:-25}", the target
   landing 25px UNDER the header.

   MEASURED 2026-09-05, `.cw-headwrap` height while scrolled (the state that
   matters, since `.cw-scrolled` shrinks the logo AND collapses the shortcut
   labels), on the homepage and a category page at thirteen widths:

       width   home   category    worst
       1440    203      203        203
        950    203      203        203     <- department bar visible
        900    162       96        162     <- bar hidden; home keeps shortcuts
        430    162       96        162
        390    160       95        160
        320    154       88        154

   The homepage is the worst case at every width below 901 because the shortcut
   row is inside the wrapper and only that page renders it. Each value below is
   the worst case for its range plus ~12px of air, which is the convention the
   original numbers used.

   ⚠️ 900 AND 700 COLLAPSE INTO ONE RULE NOW. brand.css needed two because the
   search row existed only below 700; it does not exist at all any more. Do not
   re-add a 700px breakpoint here without measuring one — the two ranges are
   genuinely the same height today.
   ========================================================================= */

html { scroll-padding-top: 215px; }

@media (max-width: 900px) { html { scroll-padding-top: 174px; } }

/* =========================================================================
   11. THE PHONE GALLERY  (D14)

   divinehindu, measured at 390x844:

       .pdp-main      358 x 358, 14px radius, inset 16px each side
       .pdp-thumbs    64px strip beneath it
       total          432px

   Ours before this: a 390px-wide image starting at x=24, i.e. 24px OFF THE
   RIGHT EDGE of the screen, with the product visibly off-centre and clipped.
   It was live in that state. The cause is the platform's own `w-screen` slide
   inside a container padded to the 24px content frame.

   🔴 THE SLIDE STAYS 100vw. Do not "fix" the overflow by narrowing it — the
   platform's carousel script translates by `window.innerWidth` per slide, so
   any other slide width desynchronises the carousel cumulatively. The view is
   overridden to a native scroll-snap strip for that reason (see the header of
   products/view/gallery/mobile.blade.php), and the 16px inset is applied to
   the IMAGE, which is where divinehindu's is too.
   ========================================================================= */

@media (max-width: 1179px) {
	/* 🔴 `min-width: 0` ON THE PARENT IS WHAT MAKES ALL OF THIS WORK, and
	   leaving it out made the gallery 728px wide inside a 390px screen.

	   The gallery's parent is an unnamed <div> that is a FLEX ITEM of the
	   product page's two-column row. A flex item's automatic minimum size is
	   its CONTENT, so the item refused to shrink below the track's natural
	   width — eleven slides — and grew to 680px, taking `.cw-gal` (parent +
	   48) to 728px and the image to 696px.

	   `overflow-x: auto` on the track does not prevent that on its own: the
	   track is `width: 100%` of a box whose own width is being decided by this
	   very content. The chain has to be broken above it.

	   ⚠️ SELECTED BY WHAT IT CONTAINS. That div has no class of its own, and a
	   positional selector would start matching something else the first time
	   the platform reorders that row. */
	.cw-body div:has(> .cw-gal) { min-width: 0; }

	/* Break out of the content frame and back onto the viewport. The parent's
	   padding is the 24px frame; -24px puts x=0 under the first pixel.
	   `max-width` is the belt: if a future layout change grows the parent
	   again, the gallery clips instead of pushing the page sideways. */
	.cw-body .cw-gal {
		margin-inline: -24px;
		max-width: 100vw;
	}

	.cw-body .cw-gal__track {
		display: flex;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;
	}

	.cw-body .cw-gal__track::-webkit-scrollbar { display: none; }

	/* ⚠️ `flex: 0 0 100%`, NOT `width: 100%`. A flex item's basis is its
	   content by default and these are images: without the `0 0` the slides
	   shrink to share one screen instead of queueing up one per screen. */
	.cw-body .cw-gal__slide {
		flex: 0 0 100%;
		scroll-snap-align: center;
		display: grid;
		place-items: center;
		padding-inline: 16px;
	}

	.cw-body .cw-gal__media {
		width: 100%;
		aspect-ratio: 1 / 1;
		object-fit: cover;
		border-radius: 14px;
		background: var(--cw-color-ground-alt, #FBF3E2);
	}

	.cw-body .cw-gal__shim {
		aspect-ratio: 1 / 1;
		margin-inline: 16px;
		border-radius: 14px;
		background: #E8E8EA;
	}

	/* ---- the thumbnail strip ---- */

	.cw-body .cw-gal__thumbs {
		display: flex;
		gap: 8px;
		overflow-x: auto;
		scrollbar-width: none;
		padding: 12px 16px 0;
	}

	.cw-body .cw-gal__thumbs::-webkit-scrollbar { display: none; }

	.cw-body .cw-gal__thumb {
		flex: 0 0 auto;
		width: 56px;
		height: 56px;
		padding: 0;
		border: 2px solid transparent;
		border-radius: 10px;
		background: var(--cw-color-ground-alt, #FBF3E2);
		cursor: pointer;
		overflow: hidden;
		/* The strip is 64px on divinehindu: 56px of thumbnail plus the 8px of
		   padding above it. */
		line-height: 0;
	}

	.cw-body .cw-gal__thumb img {
		width: 100%;
		height: 100%;
		object-fit: cover;
		border-radius: 8px;
	}

	.cw-body .cw-gal__thumb--on {
		border-color: var(--cw-color-maroon, #6C1322);
	}
}

/* =========================================================================
   12. THE PRODUCT TAB STRIP ON A PHONE  (D16)

   divinehindu: one 56px strip — Description · Specification · Benefits · FAQs —
   with one panel below it. Ours below 1180px was a stack of always-open
   accordions that ran the page to 4,900px and put Reviews ~3,000px down.

   The same Vue strip now renders at every width (see the theme's
   products/view.blade.php). The vendor sizes it for a desktop: `px-8 py-5
   text-xl` on each tab, which is ~110px per tab before the label — four tabs
   is well over 390px. It is resized here and allowed to scroll sideways, which
   is what divinehindu's own strip does.
   ========================================================================= */

@media (max-width: 1179px) {
	/* The strip itself. `position: relative` so the active underline the
	   vendor draws stays with its tab rather than the page. */
	.cw-body .cw-pdptabs {
		margin-top: 18px;
	}

	/* ⚠️ SELECTED BY THE VENDOR'S OWN CLASSES, which is ugly and is still the
	   right trade here: the tab buttons carry no id or data attribute, and a
	   positional selector would break the first time a tab is added. If the
	   vendor's padding scale changes this rule stops applying and the strip
	   goes back to being too wide — VISIBLY, which is the failure worth having.
	   `[role="button"][id$="-button"]` is the shape every tab head has. */
	.cw-body .cw-pdptabs [role="button"][id$="-button"] {
		padding: 14px 14px;
		font-size: .9375rem;
		white-space: nowrap;
		flex: 0 0 auto;
	}

	/* The row the tab heads sit in. Horizontal scroll rather than wrapping:
	   a wrapped strip changes height as tabs are added and pushes the panel
	   down by a line, which reads as the page jumping. */
	.cw-body .cw-pdptabs [role="button"][id$="-button"]:first-child { margin-left: 4px; }

	.cw-body .cw-pdptabs > div > div:first-child {
		display: flex;
		overflow-x: auto;
		scrollbar-width: none;
		justify-content: flex-start;
	}

	.cw-body .cw-pdptabs > div > div:first-child::-webkit-scrollbar { display: none; }

	/* The panels keep the content frame; only the strip breaks out of it. */
	.cw-body .cw-pdptabs .cw-tabpanel {
		padding-inline: 20px;
	}
}

/* =========================================================================
   13. THE PRODUCT CARD — divinehindu's, measured  (D18, D19)

   Measured side by side at 390x844 on 2026-09-05:

                      Crystalwala              divinehindu
       card           181x419, 1px border,     180x437, no border,
                      16px radius, white       6px radius, cream, soft shadow
       image          150x150 inside a 179     fills 180x225, edge to edge
                      box — ~30px of dead
                      white on every card
       discount       mint pill FLOATING       green pill INLINE in the
                      over the photograph      price row
       price          MRP struck above,        [OFF] [struck MRP] on one line,
                      price below              price bold underneath
       title          16px / 600               12px / 600
       button         "Choose options"         "Add to cart"

   ⚠️ THE BUTTON LABEL IS THE ONE THING NOT COPIED (D19). divinehindu sells no
   configurable products; 155 of ours have variants a shopper must choose
   before anything can go in a basket. "Add to cart" on those would either lie
   or skip the picker, so the label stays driven by the product type. Everything
   else on this list is copied.
   ========================================================================= */

/* ---- the card itself ---- */

.cw-body .cw-card {
	border: 0;
	border-radius: 6px;
	background: var(--cw-color-ground, #FFFAEB);
	box-shadow: 0 1px 6px rgba(0, 0, 0, .05);
	padding-bottom: 12px;
	overflow: hidden;
}

/* ---- the image ----

   🔴 THIS REVERSES A DELIBERATE DECISION, and storefront.css:554 states the
   opposite in as many words:

       "Square, not portrait: the client's source photographs are
        overwhelmingly square, so a taller well only adds dead space
        beneath each product."

   That reasoning was sound and the owner overrode it knowingly on 2026-09-05,
   having been shown the measurement: our photographs run 1.00 to 1.24 (square
   to landscape, never portrait), so filling a 4:5 well means `cover` CROPS
   about 22px off EACH SIDE of a square photograph. On a tight product crop that
   cuts into the piece. The alternatives — a square well, or letterboxing inside
   a 4:5 one — were both offered and declined in favour of matching divinehindu
   exactly.

   ⚠️ IF PRODUCTS START LOOKING CLIPPED, THIS IS WHY, and the fix is one line:
   `object-fit: contain` here letterboxes instead of cropping.

   ⚠️ THE `!important` ON `padding` IS ANSWERING ANOTHER ONE, and without it
   this rule looks like it has not loaded. brand.css:1438 sets

       .cw-card__media { padding: 8% !important; background: #FFF !important; }

   `!important` beats ordinary declarations at ANY specificity, so the
   photograph stayed inset by 14.5px on each side and `ui:browser` reported
   "fills=false fit=cover" — the fit was right and the box was not.

   ⚠️ AND THAT RULE HAS A REASON, WHICH THIS CHANGE RETIRES RATHER THAN
   IGNORES. Read brand.css:1420: the client's photographs are cut-outs on mixed
   grounds, and the white well plus padding existed so a white-ground shot and a
   black-velvet shot would read as one catalogue. With `cover` and no padding
   there IS no visible well — each photograph fills its own tile, so its own
   ground becomes the tile's colour. A white-ground and a black-ground product
   side by side will now look more different from each other than they did.
   That is a consequence of D18, not an oversight; CW-15 (mirror the images
   locally, normalise the grounds) is the real fix and is already ticketed.

   The background below only shows if an image fails to load. */
.cw-body .cw-card__media {
	aspect-ratio: 4 / 5;
	padding: 0 !important;
	margin: 0;
	/*
	 * 🔴 WHITE, AND THIS LINE HAS BEEN WRONG SINCE THE CW-58 CLONE PASS.
	 * It read `var(--cw-color-ground-alt)` — beige — which silently reverted a
	 * decision brand.css:1447 had already taken and explained: the catalogue's
	 * photographs are cut-outs on MIXED grounds, so the well has to be the
	 * ground most of them already use, or every tile shows a different-coloured
	 * rectangle.
	 *
	 * Measured 2026-09-11: 10 of 12 sampled photographs sit on white, 1 black,
	 * 1 brown. Against a beige well all twelve showed a visible block; against
	 * white, ten have no visible edge at all, and the dark ones read as a
	 * deliberate dark photograph rather than a hole.
	 *
	 * The owner reported it as "products are not showing in proper boundaries...
	 * image is cut from its price and descriptions" — the beige well WAS that
	 * band across the card.
	 *
	 * ⚠️ `!important` IS REQUIRED, not decoration: brand.css:1447 carries
	 * `background: #FFFFFF !important`, and an ordinary declaration here loses
	 * to it whatever the specificity. Both are important; this one wins on
	 * specificity (0,2,0 against 0,1,0) and source order.
	 *
	 * ⚠️ NOT A SUBSTITUTE FOR CW-21. Normalising the photography onto one
	 * ground is the real fix; it needs the images mirrored locally first
	 * (CW-15). This makes the majority case invisible in the meantime.
	 */
	background: #FFFFFF !important;
	border-radius: 0;
}

.cw-body .cw-card__media .cw-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ---- title, rating ---- */

.cw-body .cw-card__title {
	padding-inline: 10px;
	margin-top: 10px;
	font-size: .75rem;
	line-height: 1.3;
}

.cw-body .cw-card__rating { margin-top: 4px; }
.cw-body .cw-card__score  { font-size: .71875rem; color: var(--cw-color-maroon, #6C1322); }
.cw-body .cw-card__count  { font-size: .71875rem; }

/* ---- the price row ----

   ⚠️ `display: contents` ON `.cw-card__price` IS THE WHOLE TRICK. That div's
   contents are `v-html` from the API — two <p>s we do not author — so they
   cannot be given flex `order` while their parent is a box. `contents` removes
   the parent from the layout and promotes both <p>s to items of the row, with
   no change to what the API sends.

   ⚠️ AND THE ROW MUST SURVIVE PIECES BEING ABSENT. A product that was never
   marked down has no pill and no struck price; a configurable renders "As low
   as ₹1,490.00" as a single <p>. A fixed two-column grid leaves a hole in both
   cases. A wrapping flex row centres whatever is present. */
.cw-body .cw-card__pricerow {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 3px 6px;
	padding-inline: 10px;
	margin-top: 8px;
}

.cw-body .cw-card__price { display: contents; }

/* The pill, and the struck MRP beside it, share the first line. */
.cw-body .cw-card__pricerow .cw-badge--sale {
	position: static;
	order: 1;
	margin: 0;
	padding: 3px 7px;
	border-radius: 4px;
	/* divinehindu's discount green. Not a brand token on either site — it is
	   the universal "this is money off" colour, and our mint read as a status
	   chip rather than a saving. */
	background: #43A047;
	color: #FFF;
	font-size: .625rem;
	font-weight: 800;
	letter-spacing: .02em;
	line-height: 1.4;
	white-space: nowrap;
}

/* ⚠️ TWO SELECTORS FOR ONE THING, because there are two cards.
   `.line-through` is Tailwind's, in the HTML the listing API sends;
   `.cw-money--was` is ours, in the server-rendered tile the home page uses.
   Both must match, and the "paid price" rule below must exclude BOTH — it
   matched the struck price too when only one was listed, and every home tile
   rendered two 87px price blocks. */
.cw-body .cw-card__price > .line-through,
.cw-body .cw-card__price > .cw-money--was {
	order: 2;
	font-size: .84375rem;
	font-weight: 500;
	color: #9B9B9B;
	margin: 0;
}

/* ⚠️ `flex-basis: 100%` IS WHAT PUTS THE PRICE ON ITS OWN LINE. Without it the
   three items share one row, the row overflows a 180px card, and the price
   ends up beside the pill instead of under it.

   ⚠️ AND `text-align` IS NOT REDUNDANT WITH THE ROW'S `justify-content`. That
   centres flex ITEMS; this item is a full-width line, so its own text alignment
   is what positions the glyphs inside it. Without this the price sits hard left
   under a centred pill — which is what shipped in the first pass and reads as a
   mistake rather than a style. */
.cw-body .cw-card__price > :not(.line-through):not(.cw-money--was) {
	order: 3;
	flex-basis: 100%;
	margin: 0;
	text-align: center;
	font-size: 1rem;
	font-weight: 800;
	color: var(--cw-color-ink, #35251D);
}

/* ---- the badge row and the button, sized to the smaller card ---- */

.cw-body .cw-card .cw-tilebadges { margin: 6px 0 2px; }

.cw-body .cw-card__cta {
	padding-inline: 10px;
	margin-top: 8px;
}

.cw-body .cw-card__cta > a,
.cw-body .cw-card__cta > button {
	display: grid;
	place-items: center;
	width: 100%;
	min-height: 33px;
	padding: 6px 8px;
	border-radius: 4px;
	font-size: .75rem;
	font-weight: 700;
	line-height: 1.2;
}

/* =========================================================================
   14. THE TOP BANNER — divinehindu's bar  (D21)

   Measured on divinehindu: 28px tall, one CENTRED line, white on maroon
   rgb(94,20,32), 15px. Plus a "Track Your Order" pill on the right at desktop
   widths.

   Ours held three claims in a three-column grid, gold on maroon, with two of
   them hidden below 860px — so a phone saw one item sitting in the middle
   column of a grid built for three, and a desktop saw a row rather than a line.

   ⚠️ NO "TRACK YOUR ORDER". It is the one part of that bar that is not copied,
   and CLAUDE.md says why in as many words: the platform ships no guest
   order-tracking route on the shop side, so the link would go nowhere. That is
   the dead link CW-09 forbids.

   🔴 THE WORDING IS STILL OURS AND IS A PENDING QUESTION — docs/DH-CLONE.md
   §11. divinehindu's line is "Flat 25% Cashback - Limited Offer", a specific
   promotional offer Crystalwala does not currently run. This block styles the
   bar; the words are one string in header/index.blade.php.
   ========================================================================= */

.cw-body .cw-announce {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: .5rem;

	/* ⚠️ EVERY VALUE BELOW IS MEASURED OFF divinehindu.in's `.topbar__msg`,
	   NOT CHOSEN. Read at 390x844 AND at 1440x900 on 2026-09-05 -- their bar is
	   THE SAME AT BOTH, which is why there is no media query under this block
	   any more. Their numbers:

	       font-family    Inter, sans-serif
	       font-size      13.5px
	       font-weight    600
	       letter-spacing normal
	       line-height    20.25px  (= 1.5)
	       colour         #FFF
	       strip height   28.3px   (20.25 + 4px padding top and bottom)

	   Ours read Poppins / 13px / .26px tracking / 18.2px on a 30.2px strip.
	   Three of those four were inherited by accident, not declared here. */

	/* Poppins arrived by INHERITANCE from the body stack -- nothing in the six
	   stylesheets ever set a family on this bar, so it silently took whatever
	   the platform put on <body>. `--cw-font-body` is already Inter (CW-41,
	   tokens.css:45), so this is a declaration, not a new font: nothing extra
	   is downloaded. */
	font-family: var(--cw-font-body);

	/* 13.5px at EVERY width. Not a rem: the reference is a measured pixel value
	   and expressing it as .84375rem would silently depend on the root size. */
	font-size: 13.5px;
	line-height: 1.5;

	/* ⚠️ NOT REDUNDANT. storefront.css:39 sets `letter-spacing: .02em` on
	   `.cw-announce`, which at 13.5px is .27px of tracking divinehindu does not
	   have. Their value is `normal`, and `normal` is not the same as `0` -- it
	   lets the font's own kerning stand. This overrides that rule; deleting the
	   line does not restore the default, it restores storefront.css's. */
	letter-spacing: normal;

	/* 4px, not 6px: 20.25px of line plus 8px of padding is their 28.3px bar. */
	padding-block: 4px;

	text-align: center;
	/* divinehindu's bar is white on maroon; ours was gold on maroon, which at
	   15px on a 28px bar reads as decoration rather than as a message. */
	color: #FFF;
}

/* ⚠️ `color` HERE IS NOT REDUNDANT WITH THE BAR'S, and leaving it out shipped
   the offer line in GOLD on maroon while the check reported white.

   storefront.css:44 sets `.cw-announce strong { color: gold }`, from when the
   bar held three claims and the middle one was emphasised. The colour on the
   bar cannot reach through that — `color` inherits, and an inherited value
   loses to any rule that sets it directly.

   🔴 AND THE CHECK PASSED ANYWAY, which is the more useful lesson. It measured
   `getComputedStyle(bar).color` — the CONTAINER's colour, which really was
   white — while every visible glyph was inside the <strong>. Assert the colour
   of the TEXT, not of the box it sits in. Same trap as the filter sidebar,
   twice (§15.2, §22.3). */
.cw-body .cw-announce strong {
	font-weight: 600;
	color: inherit;
}

/* 🔴 THE FAMILY HAS TO BE RE-DECLARED ON THE DESCENDANTS, AND THIS IS THE
   SAME BUG AS THE GOLD <strong> ABOVE, IN A SECOND PROPERTY.

   Bagisto's Vite bundle (app-*.css) contains a UNIVERSAL rule:

       * { font-family: Poppins, sans-serif; }

   Its specificity is (0,0,0), so it loses every cascade contest -- and it
   still wins here, because specificity is not what decides this. `*` matches
   the <span> and the <strong> THEMSELVES and sets the family DIRECTLY on
   them. The family set on `.cw-announce` only ever reaches them by
   INHERITANCE, and an inherited value loses to any rule that sets the
   property directly, at any specificity.

   Measured live after the first deploy of this block: the bar computed to
   Inter and every visible glyph inside it still computed to Poppins.

   ⚠️ `inherit` WOULD NOT FIX IT EITHER -- it would inherit from the <span>,
   which `*` has also already set to Poppins. The value has to be named. */
.cw-body .cw-announce,
.cw-body .cw-announce * {
	font-family: var(--cw-font-body);
}

/* ⚠️ ONE LINE, AT EVERY WIDTH. The other two claims are still in the markup —
   they are true, they are used nowhere else, and `display: none` keeps them one
   deleted rule away. brand.css already hid them below 860px; this extends that
   to the desktop, which is what makes the bar a LINE rather than a row. */
.cw-body .cw-announce > :first-child,
.cw-body .cw-announce > :last-child { display: none; }

/* ⚠️ THE PHONE OVERRIDE IS DELETED ON PURPOSE, NOT LOST.
   It read `@media (max-width: 900px) { font-size: .8125rem }` -- 13px on a
   phone against 15px on the desktop. divinehindu does not do that: measured at
   390 and at 1440, their bar is 13.5px at both. Re-adding a phone size here
   would put the two references back out of step, which is the whole point of
   the block above. */

/* =========================================================================
   15. THE LISTING TOOLBAR, COMPACTED  (D22, D23)

   THE BUG, measured on /rudraksha at 390x844 before this block:

       Filters            100 x 31   at y=180
       "Price: high to low" 154 x 54 at y=169
       "12"                  61 x 54 at y=169

   Three controls on one row at two different heights, none of them sharing a
   baseline — §5 gave the Filters toggle its own compact padding and left the
   platform's `p-3.5` (14px) on the other two. That is the "not properly
   rendering" in the report, and no amount of aligning fixes it while the boxes
   are 23px apart in height.

   AND THE STACK ABOVE IT WAS PAYING TWICE FOR THE SAME AIR:

       .cw-cathead        padding-block 10   \\  48px of padding around a
       .cw-cathead__inner padding-block 14   /   22px line of type
       ---------------------------------------------------------------
       title band                        71px
       toolbar                           54px
       count + its margins               55px
       ---------------------------------------------------------------
       first product at y=278

   D22 empties the row: sort and page size move into the panel, as they are on
   divinehindu at every width. D23 keeps the count on its own line but tightens
   it. Measured result is the first product at y≈190.
   ========================================================================= */

/* ---- the title band: one padding, not two ---- */

.cw-body .cw-cathead__inner {
	/* ⚠️ THE OUTER `.cw-cathead` ALREADY HAS 10px (§4). This element having 14
	   of its own is where 28 of the band's 71px came from — and it is invisible
	   in either rule on its own, which is why it survived the first pass. */
	padding-block: 0;
}

.cw-body .cw-cathead { padding-block: 8px; }

/* ---- the row: one control ---- */

.cw-body .cw-filterbar {
	margin-top: 4px;
	margin-bottom: 0;
}

@media (max-width: 767px) {
	/* 36px, and the same 36px the panel's own pills use. */
	.cw-body .cw-filterbar__toggle {
		min-height: 36px;
		padding: 0 .875rem;
	}
}

/* ---- the count: its own line, tighter ---- */

.cw-body .cw-count {
	margin: 10px 0 0;
	font-size: .8125rem;
}

/* ⚠️ THE GRID'S OWN TOP MARGIN IS THE OTHER HALF OF THAT GAP. `.mt-8` on the
   grid's wrapper is 20px on top of the count's own margin; together they were
   40px between one line of text and the first photograph. */
@media (max-width: 767px) {
	.cw-body .cw-listing__main > div[class*="mt-8"] { margin-top: 10px; }
}

/* =========================================================================
   16. SORT, INSIDE THE PANEL — divinehindu's SORT BY pills  (D22)

   divinehindu's filter panel opens with a "SORT BY" heading over a wrap of
   pills: Best Selling · Newest · Price: Low to High · Price: High to Low · A-Z.

   ⚠️ THAT LIST ALREADY EXISTS IN THE PLATFORM'S MARKUP and no new template was
   needed. `categories/toolbar.blade.php` ships TWO branches: a `max-md:hidden`
   desktop row of dropdowns, and an `md:hidden` branch that is a bare, unstyled
   <ul> of exactly these sort options. brand.css:4573 hides that <ul> and shows
   the dropdowns on phones instead, because the <ul> was written for a drawer
   that no longer existed and rendered as 255px of plain text above the grid.

   Inside the panel it is the right control after all, and it is what
   divinehindu shows. So the flip is reversed HERE ONLY — scoped to
   `.cw-filterpanel`, so §5's fix for the bar keeps applying anywhere the bar
   still has tools.

   ⚠️ THE PAGE-SIZE CONTROL IS GONE ON PHONES, and that is deliberate: it lives
   only in the desktop branch, neither reference site has one, and the grid
   already has a Load more button. Desktop keeps both dropdowns.
   ========================================================================= */

@media (max-width: 767px) {
	.cw-body .cw-filterpanel .cw-filterbar__tools .max-md\:hidden { display: none !important; }
	.cw-body .cw-filterpanel .cw-filterbar__tools .md\:hidden     { display: block !important; }

	/* The heading divinehindu puts above the pills. There is no element for it
	   in the platform's markup, so it is drawn rather than added — which keeps
	   this a pure restyle of a view we do not own. */
	.cw-body .cw-filterpanel .cw-filterbar__tools::before {
		content: "Sort by";
		display: block;
		margin-bottom: 8px;
		font-size: .6875rem;
		font-weight: 700;
		letter-spacing: .12em;
		text-transform: uppercase;
		color: var(--cw-color-muted, #7A6A5F);
	}

	.cw-body .cw-filterpanel .cw-filterbar__tools ul {
		display: flex;
		flex-wrap: wrap;
		gap: 8px;
		padding: 0;
		margin: 0;
		list-style: none;
	}

	.cw-body .cw-filterpanel .cw-filterbar__tools li {
		/* Overrides the vendor's `px-4 py-2.5`, which was sized for rows in a
		   drawer rather than for pills. */
		padding: 8px 14px;
		border: 1px solid var(--cw-color-line, #E7D9C4);
		border-radius: 999px;
		background: #FFF;
		font-size: .8125rem;
		line-height: 1;
		white-space: nowrap;
		cursor: pointer;
	}

	/* ⚠️ THE VENDOR MARKS THE CHOSEN OPTION WITH `bg-gray-100`, a Tailwind
	   utility bound with `:class`. It is the only signal of which sort is
	   active, so it is restyled rather than replaced — if the vendor's class
	   ever changes, the pill loses its highlight VISIBLY instead of the
	   selection silently becoming unreadable. */
	.cw-body .cw-filterpanel .cw-filterbar__tools li.bg-gray-100 {
		background: var(--cw-color-maroon, #6C1322) !important;
		border-color: var(--cw-color-maroon, #6C1322);
		color: #FFF;
		font-weight: 600;
	}

	.cw-body .cw-filterpanel .cw-filterbar__tools {
		width: 100%;
		margin: 0 0 16px;
		padding-bottom: 16px;
		border-bottom: 1px solid var(--cw-color-line, #E8DCC8);
	}
}

/* =========================================================================
   17. THE PERMANENT LEFT SIDEBAR  (D26)

   certifiedcrystal.com's collection page, measured at 390x844:

       group tabs   45px, full width, sticky
       icon rail    72px column, sticky, scrolls inside itself
       content     318px

   ⚠️ THIS PARTLY REVERSES D10. That decision chose a drawer *because* a
   permanent 72px rail leaves 318px, which is two cards at ~150px — smaller
   than the 160px before this work and below D5's 181px. The owner asked for
   the permanent rail anyway, with the reference screenshot. The narrower card
   is the stated cost, not an accident.

   ⚠️ THE RAIL IS ONE ELEMENT CONTAINING BOTH THE TABS AND THE LIST, and they
   have to land in different places: tabs across the top, list down the left.
   `display: contents` on the rail and its panel promotes both to grid items of
   `.cw-catwrap`, so one partial serves two layouts with no duplicated markup.
   Selector matching is unaffected by it, so the `:has()` rules above still
   work.
   ========================================================================= */

@media (max-width: 900px) {
	.cw-body .cw-catwrap {
		display: grid;
		grid-template-columns: 72px minmax(0, 1fr);
		grid-template-areas:
			"tabs tabs"
			"rail main";
		align-items: start;
	}

	.cw-body .cw-rail--side,
	.cw-body .cw-rail--side .cw-rail__panel { display: contents; }

	.cw-body .cw-rail--side .cw-rail__tabs {
		grid-area: tabs;
		position: sticky;
		/* Under the pinned header. 95px is the measured height of `.cw-headwrap`
		   on a listing page — announcement 27 + row 68 — and the shortcut row
		   does not render here (D8), so it is a constant on these two pages. */
		top: 95px;
		z-index: 30;
		margin: 0;
	}

	.cw-body .cw-rail--side .cw-rail__lists {
		grid-area: rail;
		position: sticky;
		/* header + the tab strip above it */
		top: 143px;
		max-height: calc(100vh - 143px - var(--cw-tabbar-h, 72px));
		overflow-y: auto;
		overscroll-behavior: contain;
		scrollbar-width: none;
		padding: 4px 0 8px;
		border-right: 1px solid var(--cw-color-line, #E8DCC8);
		background: var(--cw-color-ground, #FFFAEB);
	}

	.cw-body .cw-rail--side .cw-rail__lists::-webkit-scrollbar { display: none; }

	.cw-body .cw-catwrap__main { grid-area: main; min-width: 0; }

	/* ---- the rail's items, at 72px ----

	   The drawer's items are a 44px icon beside a label on one line; at 72px
	   the label has to go under the icon, as certifiedcrystal's does. */
	.cw-body .cw-rail--side .cw-rail__item {
		flex-direction: column;
		gap: 4px;
		padding: 8px 4px;
		text-align: center;
		font-size: .625rem;
		line-height: 1.15;
	}

	.cw-body .cw-rail--side .cw-rail__icon {
		width: 46px;
		height: 46px;
	}

	/* ⚠️ THE LABEL MUST WRAP HERE, not ellipsis. The drawer's rule truncates to
	   one line because it has a wide row to fill; in a 72px column "Pendants &
	   Lockets" would become "Pen…" and every third item would be unreadable. */
	.cw-body .cw-rail--side .cw-rail__label {
		white-space: normal;
		overflow: visible;
		text-overflow: clip;
	}

	.cw-body .cw-rail--side .cw-rail__item--on {
		box-shadow: inset 3px 0 0 var(--cw-color-maroon, #6C1322);
	}

	.cw-body .cw-rail--side .cw-rail__all { margin-inline: 8px; font-size: .6875rem; }

	/* 🔴 THE GRID MUST NOT BREAK OUT OF ITS COLUMN ANY MORE. §6 gives
	   `.cw-prodgrid` `margin-inline: -16px` so it can reach the viewport edge
	   on a full-width listing. Inside the sidebar layout that margin drags the
	   grid 16px LEFT, underneath the rail, and the first card sits behind the
	   icons. The breakout is cancelled where a sidebar exists.

	   ⚠️ AND THE SELECTOR HAS TO MATCH §6's LENGTH. That rule is
	   `.cw-body main .cw-prodgrid.grid` — (0,3,1). A shorter one here loses
	   however late the file is: measured, the first card sat at x=64 against a
	   column starting at x=72, i.e. 8px under the rail. */
	.cw-body main .cw-catwrap .cw-prodgrid.grid {
		margin-inline: 0;
	}

	/* The content column carries its own gutter instead. */
	.cw-body .cw-catwrap__main .container { padding-inline: 8px !important; }
}

/* Above 900px the sidebar does not render as a column: CW-39's full-width grid
   stands (D13), and the rail is a phone and tablet control. */
@media (min-width: 901px) {
	.cw-body .cw-rail--side { display: none; }
	.cw-body .cw-catwrap { display: block; }
}

/* =========================================================================
   18. THE HOMEPAGE, COMPACTED  (D24, D25)

   MEASURED, both homepages at 390x844 on 2026-09-05:

       divinehindu   9,980px      hero 316px
       Crystalwala  14,747px      hero 658px

   48% taller, and the owner's note was blunt: "Overall height or empty space
   needs to be removed from entire website. This is not acceptable by client."

   The four biggest levers, in order:

       hero              658 -> ~320   D25
       "Pieces ready…"  1603 -> ~500   D24, grid becomes a rail
       every .cw-sec      72px of padding each, x12 sections
       rashi             341 -> ~230
   ========================================================================= */

/* ---- the hero (D25) ----

   divinehindu's hero is 316px of photograph with the words baked into the
   image. Ours is a video carrying real copy, so matching 316px means dropping
   copy, and the owner chose to: headline and one button.

   ⚠️ WHAT IS HIDDEN IS STILL IN THE HTML. The eyebrow and the descriptive
   sentence are the only place the homepage says in words what this shop sells,
   and they are read by crawlers and screen readers from the markup. Hiding
   them visually on a phone is a layout decision; deleting them would be an SEO
   one, and was not asked for. Desktop keeps all of it. */
@media (max-width: 900px) {
	.cw-body .cw-hero__wrap { padding: 28px 24px; }

	.cw-body .cw-hero .cw-tag,
	.cw-body .cw-hero__sub,
	.cw-body .cw-hero .cw-pill--ghost { display: none; }

	.cw-body .cw-hero__title { margin-bottom: 18px; }

	/* The video is `object-fit: cover`, so capping the stage crops rather than
	   squashes. 320px matches the reference.

	   🔴 `.cw-hero__wrap` MUST BE IN THIS LIST, and leaving it out cost the
	   hero its only button. The wrap carries its own min-height (658px, from
	   the full-bleed treatment), `.cw-hero` is `overflow: hidden`, and the copy
	   is bottom-aligned inside the wrap — so capping the HERO at 320 while the
	   WRAP stayed 658 clipped everything below y=500. Measured: the headline
	   sat at 431 and survived; "Shop everything" sat at 535 and was simply
	   gone. Nothing overflowed visibly and nothing errored.

	   `min-height: 0` before the height is what actually releases it — the
	   min-height wins over a smaller height otherwise. */
	.cw-body .cw-hero,
	.cw-body .cw-hero__stage,
	.cw-body .cw-hero__video,
	.cw-body .cw-hero__wrap {
		min-height: 0;
		height: 320px;
		max-height: 320px;
	}

	/* The copy block keeps its bottom alignment inside the shorter wrap. */
	.cw-body .cw-hero__wrap {
		display: flex;
		align-items: flex-end;
	}
}

/* ---- section rhythm ----

   Every `.cw-sec` carried `padding: 36px 0` — 72px per section across roughly
   twelve of them, ~860px of the page in section padding alone. 24px each is
   still a clear break between bands and returns ~290px. */
@media (max-width: 900px) {
	.cw-body .cw-sec { padding-block: 24px; }
	.cw-body .cw-sec__head { margin-bottom: 16px; }
	.cw-body .cw-band,
	.cw-body .cw-split,
	.cw-body .cw-rails,
	.cw-body .cw-promise { padding-block: 24px; }
}

/* ---- "Pieces ready to send": grid -> rail (D24) ----

   divinehindu shows its product sections as horizontal rails: a 376px window
   over 2,951px of track, cards 233px wide with the next one half in view, and
   the section 751px tall against our 1,603px grid.

   ⚠️ THE CARD IS WIDER HERE THAN IN A LISTING GRID, and that is the
   reference's own proportion — 233px in a rail against 180px in a grid. A rail
   card that matches the grid card looks like a broken grid; one that is
   visibly bigger reads as a feature. 62% of the viewport gives 232px at 390.

   ⚠️ `flex: 0 0 62%` NOT `width: 62%`. These are `<li>`s in what was a grid;
   as flex items their basis is content unless it is stated, and they collapse
   to share one screen instead of queueing up. */
@media (max-width: 900px) {
	.cw-body .cw-grid--home .cw-grid__items {
		display: flex !important;
		grid-template-columns: none !important;
		flex-wrap: nowrap;
		gap: 12px !important;
		overflow-x: auto;
		scroll-snap-type: x proximity;
		overscroll-behavior-x: contain;
		scrollbar-width: none;
		/* Break out so the rail runs to the screen edge and the last card is
		   not cut by the container's own padding — the same treatment §6 gives
		   the listing grid, and the reason the next card stays half-visible. */
		margin-inline: -24px;
		padding-inline: 24px 24px;
	}

	.cw-body .cw-grid--home .cw-grid__items::-webkit-scrollbar { display: none; }

	.cw-body .cw-grid--home .cw-grid__items > li {
		flex: 0 0 62%;
		scroll-snap-align: start;
		max-width: none;
	}

	/* The section's own side padding is now carried by the rail. */
	.cw-body .cw-grid--home { padding-inline: 24px; }
}

/* ---- the rashi rail: make the scroll visible ----

   The rail already scrolled — `overflow-x: auto` with snap points, since
   CW-47. The owner's complaint is that nothing SAYS so: the scrollbar is
   hidden and the last visible sign ends flush with the edge, so it reads as a
   row of four rather than a strip of twelve.

   divinehindu solves it with dots under the row (`.rashi-dots`). Ours are
   built by pdp.js — no markup, no dots without JavaScript, and the rail still
   scrolls either way.

   ⚠️ THE OTHER HALF OF THE FIX IS THE ITEM WIDTH. Dots tell you it scrolls;
   a half-visible sign at the right edge SHOWS you. The width is set so twelve
   never divide evenly into the viewport. */
@media (max-width: 900px) {
	.cw-body .cw-sec--rashi { padding-block: 22px; }

	.cw-body .cw-rashi--rail .cw-rashi__item { flex: 0 0 26%; }

	.cw-body .cw-rashi--rail .cw-rashi__disc {
		width: 60px;
		height: 60px;
		margin-bottom: .3rem;
	}

	.cw-body .cw-rashi--rail .cw-rashi__en { font-size: .8125rem; }
}

.cw-body .cw-dots {
	display: flex;
	justify-content: center;
	gap: 6px;
	margin-top: 12px;
}

.cw-body .cw-dots__dot {
	width: 6px;
	height: 6px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: var(--cw-color-line, #E0D2BC);
	cursor: pointer;
	transition: width .18s ease, background-color .18s ease;
}

.cw-body .cw-dots__dot--on {
	width: 18px;
	background: var(--cw-color-maroon, #6C1322);
}

@media (prefers-reduced-motion: reduce) {
	.cw-body .cw-dots__dot { transition: none; }
}

/* =========================================================================
   19. THE LAST OF THE HOMEPAGE STACKS

   After §18 the page was 13,446px against divinehindu's 9,980. What was left
   was four sections rendering as SINGLE-COLUMN stacks of large cards on a
   phone — measured:

       .cw-cats           6 x 257 = 1,627px   one column
       .cw-journal__grid  3 x 412 = 1,273px   one column
       .cw-why__grid      4 items =   729px   one column
       .cw-intent         6 x 115 =   777px   one column

   Two of them halve cleanly and two do not, and the difference is what is
   inside the card rather than how tall it is:

   ⚠️ `.cw-intent` AND `.cw-why` ARE LEFT ALONE ON PURPOSE. Their cards are
   HORIZONTAL — a round image on the left, a title, a subtitle and a count on
   the right, in 310x115. Halving the width to 162px does not halve the height;
   it forces the content to stack and the card gets TALLER while looking worse.
   `.cw-intent` is already only 115px per row, which is compact for what it
   carries. Do not "finish the job" here without measuring it.
   ========================================================================= */

@media (max-width: 900px) {
	/* ---- Shop by category: 6 stacked cards -> 2 across ----

	   These are navigation, not merchandise, so they stay a GRID rather than
	   becoming a rail: all six visible at once beats four hidden behind a
	   scroll when the job is "where do I go". Their cards are a picture over a
	   label, so halving the width halves the height. */
	.cw-body .cw-cats {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px;
	}

	/* ---- From the journal: 3 stacked cards -> a rail ----

	   Reading is secondary to buying on a homepage, and there are only three,
	   so a rail with the next one half in view costs nothing and returns
	   ~840px. Same treatment as the product rail in §18, and it opts into the
	   same dots. */
	.cw-body .cw-journal__grid {
		display: flex !important;
		grid-template-columns: none !important;
		flex-wrap: nowrap;
		gap: 12px !important;
		overflow-x: auto;
		scroll-snap-type: x proximity;
		overscroll-behavior-x: contain;
		scrollbar-width: none;
		margin-inline: -24px;
		padding-inline: 24px;
	}

	.cw-body .cw-journal__grid::-webkit-scrollbar { display: none; }

	.cw-body .cw-journal__grid > li {
		flex: 0 0 76%;
		scroll-snap-align: start;
		max-width: none;
	}
}

/* =========================================================================
   20. TWO CONSEQUENCES OF THE SIDEBAR, CAUGHT BY THE LIVE SUITE

   Both were found by `ui:browser:live` after D26 shipped, and both are the
   sidebar's doing rather than pre-existing faults.
   ========================================================================= */

/* ---- 1. the listing no longer cleared the services strip ----

   Measured on /malas and /rudraksha-bracelets: `gapBtnToUsp = 0`. The Load
   More button's bottom edge touched the white services band exactly, so it
   read as belonging to the band below rather than to the grid above — which is
   the exact fault the check at verify.mjs:1571 was written for, returning.

   ⚠️ THE CAUSE IS THE NEW WRAPPER, NOT THE OLD SPACING. `.cw-catwrap` closes
   immediately after `<v-category>`, and the margin that used to separate the
   listing from the band was on content that is now a grid item inside it —
   grid items do not push their container's edge outward the way a collapsing
   margin did. The wrapper has to carry the gap itself. */
.cw-body .cw-catwrap { padding-bottom: 32px; }

/* ---- 2. the price row wrapped at 145px ----

   D26's 318px column gives 145px cards, and at that width the pill and the
   struck MRP no longer share a line: measured pill y=554, struck y=579, price
   y=598 — three lines where §13 intends two.

   certifiedcrystal, whose card width this now matches, solves it by making all
   three smaller rather than by stacking them. Same here: the type comes down
   only inside the sidebar layout, so the 182px home-rail cards and the desktop
   grid keep §13's sizes.

   ⚠️ MEASURE THIS ON THE WIDEST PRICE IN THE CATALOGUE, not the first card to
   hand. The first attempt shrank the type and still wrapped, and it wrapped
   only on SOME categories: /crystals-stones-tumbles-raw carries "₹5,699.00"
   and fit, /rudraksha "₹16,999.00" and /malas "₹26,499.00" did not. Spot-check
   a five-figure MRP.

   Old arithmetic at 145px: 10px padding each side leaves 125px. Pill ~52 + gap 6 +
   struck ~62 = 120. */
@media (max-width: 900px) {
	.cw-body .cw-catwrap .cw-card__pricerow {
		gap: 2px 4px;
		padding-inline: 6px;
	}

	.cw-body .cw-catwrap .cw-card__pricerow .cw-badge--sale {
		padding: 3px 4px;
		font-size: .53125rem;
	}

	.cw-body .cw-catwrap .cw-card__price > .line-through,
	.cw-body .cw-catwrap .cw-card__price > .cw-money--was {
		font-size: .75rem;
	}

	.cw-body .cw-catwrap .cw-card__price > :not(.line-through):not(.cw-money--was) {
		font-size: .9375rem;
	}

	/* The title and the badge labels come down with them, or the card reads as
	   a small photograph under large type. */
	.cw-body .cw-catwrap .cw-card__title { font-size: .6875rem; }
	.cw-body .cw-catwrap .cw-tilebadges__label { font-size: .4375rem; }
	.cw-body .cw-catwrap .cw-card__cta > a,
	.cw-body .cw-catwrap .cw-card__cta > button { font-size: .6875rem; }
}

/* =========================================================================
   21. THE LISTING HEAD ON ONE LINE, AND THE COUNT AT THE BOTTOM

   Owner, on the deployed sidebar layout:
     1. "Filters button and Heading should be in one line so we don't waste
        vertical space."
     2. "Also we can move — Showing X in Y at the bottom."
     3. "The bottom section — 'Checked before dispatch and all' is mixing with
        Load more button with no space in between."

   (3) is §20 above and was already fixed; it is only unfixed on the deployed
   build. (1) and (2) are here.

   🔴 (1) IS THE THING D4 COULD NOT DO, AND THE OBSTACLE HAS NOT CHANGED.
   The Filters button lives inside `#v-category-template`, a
   `<script type="text/x-template">` compiled by Vue after mount. The `<h1>` is
   server-rendered in `.cw-cathead`, outside `<v-category>` and therefore
   outside that component's scope. They cannot share a flex parent, and moving
   the heading into the template would put the page's only H1 inside a <script>
   tag — absent from the served HTML.

   So they are laid on one line WITHOUT sharing a parent: the title band keeps
   its own height, and the filter row is pulled up into it by exactly that
   height and aligned right. No markup moves, the H1 stays server-rendered, and
   the two elements never overlap because the title is width-capped below.

   ⚠️ THE PULL MUST EQUAL THE BAND'S REAL HEIGHT. It is 39px — 8px padding
   top and bottom around a 22-23px line (§15 removed the double padding). If
   the title's type ever changes, re-measure: too little and they still stack,
   too much and the button climbs into the tab strip above. */

@media (max-width: 900px) {
	.cw-body .cw-catwrap__main .cw-cathead { position: relative; z-index: 1; }

	.cw-body .cw-catwrap__main .cw-listing {
		margin-top: -39px;
	}

	.cw-body .cw-catwrap__main .cw-filterbar {
		justify-content: flex-end;
		margin-top: 0;
		/* Clear of the title, which is capped below. */
		position: relative;
		z-index: 2;
	}

	/* ⚠️ THE CAP IS WHAT KEEPS THEM APART. "Numerology & Remedies" is 21
	   characters; without a cap it runs under the button and the two overlap.
	   55% leaves the button its ~100px and ellipses anything longer, which is
	   the honest failure — the full name is still the <h1> in the markup and
	   still in the page title. */
	.cw-body .cw-catwrap__main .cw-cathead__title {
		max-width: 55%;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	/* ---- (2) the count goes to the bottom ----

	   `.cw-count` is the first child of `.cw-listing__main`, before the grid.
	   Ordering it last needs the parent to be a flex column — which it is not
	   by default, so that is set here rather than by moving the markup. Vue
	   owns the contents of that element and re-renders them; CSS order survives
	   a re-render, a moved node would not. */
	.cw-body .cw-catwrap__main .cw-listing__main {
		display: flex;
		flex-direction: column;
	}

	.cw-body .cw-catwrap__main .cw-count {
		order: 99;
		margin: 18px 0 0;
		text-align: center;
	}
}

/* =========================================================================
   22. TWO THINGS THE OWNER FOUND ON THE DEPLOYED BUILD

   1. "There is no margin/padding between filters button and top header."
   2. "The top header with 4 options is still sticky. Remove that stickiness
      from home page."
   ========================================================================= */

/* ---- 1. the listing head had nothing above it ----

   Measured on /new-arrivals: the group-tab strip ends at y=148 and the Filters
   button starts at y=148. Zero. §21 pulls the filter row up into the title
   band to put them on one line, and the band's own 8px of padding is all that
   was left between the pair and the strip above — which the title got and the
   button, being pulled up to the band's top edge, did not.

   The gap belongs to the column rather than to either element, or it has to be
   applied twice and kept in step. */
@media (max-width: 900px) {
	.cw-body .cw-catwrap__main { padding-top: 12px; }
}

/* ---- 2. the shortcut row is no longer sticky ----

   The row moved OUT of `.cw-headwrap` in the Blade — a child of a sticky
   element cannot opt out of being carried, so no rule here could have done it.
   What is left for CSS is the seam: the row used to sit inside a wrapper that
   drew the header's bottom edge, and outside it needs its own.

   ⚠️ `.cw-scrolled` STILL COLLAPSES ITS LABELS, and that is now pointless
   rather than harmful — the row scrolls away before the class matters. The rule
   lives in brand.css §5359 and is left alone: it costs nothing, and removing it
   would be a second change to CW-52's behaviour in one pass. */
.cw-body .cw-shortcuts {
	border-bottom: 1px solid var(--cw-color-line, #E8DCC8);
}

/* =========================================================================
   23. "PHYSICAL CERTIFICATE (+₹49)"  — CW-58

   certifiedcrystal puts this directly under the quantity stepper: a bold
   primary-coloured label over an 11px grey note. Ours is a real checkbox
   rather than their styled div, so it is keyboard-reachable and announced.

   🔴 The wording is the owner's, copied verbatim, and one line of it is not
   true today — docs/DH-CLONE.md §12. It is not a style question and must not
   be "tidied" here.
   ========================================================================= */

.cw-body .cw-cert {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	/* ⚠️ NO TOP MARGIN. The gap above this control is the wrapper's padding
	   (CW-65) — leaving 14px here as well stacked to 22px, which measured as
	   "too much air" against the ~8px the owner chose. */
	margin: 0;
	padding: 12px 14px;
	border: 1px solid var(--cw-color-line, #E7D9C4);
	border-radius: 10px;
	background: var(--cw-color-ground, #FFFAEB);
	cursor: pointer;
}

.cw-body .cw-cert__box {
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	margin-top: 1px;
	accent-color: var(--cw-color-maroon, #6C1322);
	cursor: pointer;
}

.cw-body .cw-cert__text { display: grid; gap: 2px; min-width: 0; }

.cw-body .cw-cert__title {
	font-size: .875rem;
	font-weight: 700;
	color: var(--cw-color-maroon, #6C1322);
}

.cw-body .cw-cert__note {
	font-size: .6875rem;
	line-height: 1.35;
	color: var(--cw-color-muted, #7A6A5F);
}

.cw-body .cw-cert:has(.cw-cert__box:checked) {
	border-color: var(--cw-color-maroon, #6C1322);
	background: var(--cw-color-ground-alt, #FBF3E2);
}

.cw-body .cw-cert:focus-within {
	outline: 2px solid var(--cw-color-maroon, #6C1322);
	outline-offset: 2px;
}

/* =========================================================================
   24. SIX FAULTS THE OWNER FOUND ON THE FINISHED BUILD

   All six were reproduced before anything was changed, and three of them are
   mine from earlier passes.
   ========================================================================= */

/* ---- 1. the cart drawer had no quantity controls ----

   🔴 The CART PAGE has had them all along; this drawer — which opens on every
   add and is where most shoppers look — showed "Qty 2" as text. The markup is
   in the header partial; this sizes it. */

.cw-body .cw-drawer__qtyrow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	margin-top: 8px;
}

.cw-body .cw-drawer__stepper {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	border: 1px solid var(--cw-color-line, #E7D9C4);
	border-radius: 999px;
	background: #FFF;
	padding: 2px;
}

/* ⚠️ 32px, NOT 24. The cart page's own controls are 24px icons in a thin pill
   and the owner could not find them at all. WCAG 2.5.8's floor is 24px; these
   are the primary way to change an order, so they get more. */
.cw-body .cw-drawer__step {
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: var(--cw-color-maroon, #6C1322);
	font-size: 1.125rem;
	line-height: 1;
	cursor: pointer;
}

.cw-body .cw-drawer__step:hover { background: var(--cw-color-ground-alt, #FBF3E2); }
.cw-body .cw-drawer__step:disabled { opacity: .45; cursor: default; }

.cw-body .cw-drawer__qty {
	min-width: 24px;
	text-align: center;
	font-size: .875rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.cw-body .cw-drawer__remove {
	margin-top: 6px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--cw-color-muted, #7A6A5F);
	font-size: .75rem;
	text-decoration: underline;
	cursor: pointer;
}

.cw-body .cw-drawer__remove:hover { color: var(--cw-color-maroon, #6C1322); }
.cw-body .cw-drawer__remove:disabled { opacity: .45; }

/* The line that appears when the server refused the quantity change. Amber
   rather than red: nothing has gone wrong, the basket simply cannot hold
   another of that piece. */
.cw-body .cw-drawer__stuck {
	margin: .25rem 0 0;
	font-size: .72rem;
	line-height: 1.3;
	color: #92400E;
}


/* ---- 2. the certificate broke the desktop buy row ----

   🔴 `products.view.quantity.after` fires INSIDE
   `<div class="mt-8 flex max-w-[470px] gap-4 …">` — the row holding the
   quantity stepper, Add to Cart and Buy Now. The certificate became a fourth
   flex item in 470px: measured at 1440, it was squeezed to 152px wide and
   195px tall, Add to Cart stretched to 209px tall, and Add to Cart and Buy Now
   OVERLAPPED.

   ⚠️ AND FORCING IT ONTO ITS OWN LINE INSIDE THAT ROW ONLY MOVED THE DAMAGE.
   brand.css:2008 FLOATS the quantity row at 58% on desktop so Buy Now can sit
   beside it; a full-width child of that float pushed Add to Cart below Buy Now
   and broke the "Add to Cart and Buy Now share a line" check instead.

   The fix is the injection point, not CSS: the control moved to
   `additional_actions.before`, which fires after the whole buy row. Nothing
   here needs to fight the float. */
.cw-body .cw-cert {
	width: 100%;

	/* 🔴 CW-65 — "please add proper top margin of it".
	   ⚠️ `margin-top` ALONE DOES NOTHING HERE, and the measurement proves it:
	   the rule already carried `margin: 14px 0 0` and the gap on desktop was
	   exactly **0px**. brand.css:2008 FLOATS the quantity/buttons row at 58%,
	   and a float is out of normal flow — so the certificate's box started
	   level with the buttons instead of below them, and its top margin was
	   measured against the wrong thing.

	   `clear: both` puts it below the float first; only then does a margin
	   mean anything. The owner chose ~8px on 2026-09-06 — grouped with the buy
	   row it belongs to, but no longer touching it. */
}

/* CW-65 — the gap lives on the wrapper, not the control.
   ⚠️ `clear` + `margin-top` DOES NOT WORK: clearance absorbs the margin, and
   the measurement was a flat 0px on desktop with `margin-top: 14px` set. The
   wrapper clears the floated buy row and its PADDING is outside the label's
   border box, where clearance cannot reach it. */
.cw-body .cw-cert__gap {
	clear: both;
	padding-top: 8px;
}

/* ---- 3. category card titles overflowed ----

   §19 made `.cw-cats` two across, halving the card to 165px, and the title
   kept its full-width 25.6px. Measured: "Rudraksha" 138px of text in 117px of
   box, and "Gemstones" 146. Every one of the six overflowed. */
@media (max-width: 900px) {
	/* ⚠️ `.cw-cat__name`, NOT `.cw-cat__title`. The first attempt guessed the
	   class from the pattern used elsewhere and matched nothing — the titles
	   went on overflowing at exactly the measured 138/117 while the rule looked
	   correct in the file. Read the markup. */
	.cw-body .cw-cat__name {
		font-size: 1.0625rem;
		line-height: 1.15;
		word-break: break-word;
		hyphens: auto;
	}

	.cw-body .cw-cat__sub { font-size: .6875rem; line-height: 1.3; }
}

/* ---- 4. the variant picker gets a moment of attention ----

   The sticky bar's "Choose and add to basket" scrolls here. A shopper already
   near the options would otherwise see nothing move and conclude, for the
   second time, that the button is broken. */
.cw-body .cw-flash {
	animation: cw-flash 1.4s ease;
	border-radius: 12px;
}

@keyframes cw-flash {
	0%, 100% { box-shadow: 0 0 0 0 rgba(108, 19, 34, 0); }
	25%      { box-shadow: 0 0 0 4px rgba(108, 19, 34, .35); }
	60%      { box-shadow: 0 0 0 4px rgba(108, 19, 34, .35); }
}

@media (prefers-reduced-motion: reduce) {
	.cw-body .cw-flash { animation: none; box-shadow: 0 0 0 3px rgba(108, 19, 34, .35); }
}

/* ---- 5. the photographs stopped being cropped ----

   🔴 THIS REVERSES D18, at the owner's request: "The product images are
   getting cut... Can this be fixed without changing the layout?"

   `cover` in a 4:5 well loses 20% of a square photograph and up to 35% of a
   landscape one — measured across a listing: 20, 20, 20, 27, 35, 20. Our
   catalogue has no portrait images at all, so every single card was cropping.

   `contain` changes NOTHING about the layout — same well, same card height,
   same grid — and crops nothing. The photograph is smaller inside the same
   box, with the well's ground showing above and below. That was offered at
   D18 as "4:5 portrait, letterbox" and declined then; it is chosen now.

   ⚠️ IF THE CARD EVER LOOKS EMPTY, the answer is a 1:1 well (which changes
   card height), not going back to `cover`. */
.cw-body .cw-card__media .cw-img {
	object-fit: contain;
}

/* ---- 6. footer links were under the tap-target floor ----

   Found by sweeping every page type rather than reported: every footer link
   measured 17-19px tall. WCAG 2.5.8 asks for 24px, and these are the links a
   shopper reaches for when they want shipping terms or a phone number — the
   moment before they decide whether to trust the shop.

   Line-height rather than padding, so nothing about the footer's rhythm moves.
   ⚠️ `inline-block` is what makes the height take effect at all: line-height on
   an inline element does not grow its hit area. */
.cw-body .cw-footer a {
	display: inline-block;
	min-height: 24px;
	line-height: 24px;
}

/* ---- 7. the two buy buttons were different widths on a phone ----

   Not reported, found while measuring the buy row: at 390px "Add To Cart"
   rendered 112px wide against "Buy Now" at 310px, stacked. It is the vendor's
   own `max-sm:!w-auto` shrinking one and not the other, and it predates this
   work — but it reads as a mistake on the single most important control on the
   page, so it is corrected here rather than left for the client to find.

   ⚠️ Desktop is NOT touched. There the two sit side by side by design
   (brand.css:2008 floats the quantity row at 58% so Buy Now can sit beside
   it), and making them full width would stack them and undo that. */
@media (max-width: 640px) {
	.cw-body main form button.secondary-button,
	.cw-body main form button.primary-button {
		width: 100% !important;
		max-width: none !important;
	}
}

/* =========================================================================
   §25  CW-37 — "Center align the View all Crystals & Stones button", plus the
   owner's 2026-09-06 decision that these should LOOK like the button that is
   already on the page.

   Measured before: the link sat 180px left of centre inside a 601px parent,
   and rendered as 112x21 of plain text — no padding, no border, no underline.
   The same page already carries `.cw-rails__all`, a filled maroon pill. Two
   treatments for the same action.

   ⚠️ THE SELECTOR IS LISTED TWICE ON PURPOSE. brand.css:4989 sets
   `.cw-body .cw-rings .cw-more { display: inline-block }` at (0,3,1) — a plain
   `.cw-body .cw-more` is (0,2,0) and loses to it, so the rings rail would keep
   the old display and stay off-centre. Repeating the longer selector here wins
   on source order at equal specificity, which is the arbitration rule this
   theme runs on. Do not "simplify" it back to one selector.
   ========================================================================= */
.cw-body .cw-more,
.cw-body .cw-rings .cw-more {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: .4rem;
	width: fit-content;
	margin-inline: auto;          /* CW-37 — the centring itself */
	padding: .55rem 1.15rem;
	border-radius: 999px;
	background: var(--cw-color-maroon, #6C1322);
	color: #FFF7EC;
	font-weight: 600;
	text-decoration: none;
}

.cw-body .cw-more:hover {
	background: var(--cw-color-maroon-dark, #4E0D19);
	color: #FFF7EC;
	gap: .6rem;
}

/* The other treatment of the same action, centred to match.
   ⚠️ `margin-inline: auto` IS NOT ENOUGH HERE. The button lives in
   `<p class="cw-rails__more">`, a flex row with `justify-content: space-between`
   and a second child — auto margins cannot centre a flex item against its
   siblings, and it measured 70px off. The row itself has to centre.

   ⚠️ NOT APPLIED TO `.cw-sec__head--row`, deliberately. That is also
   `space-between`, but it is a section HEADER — heading on the left, link on
   the right — and centring it would collapse the heading into the link. CW-37
   names the rail button, not the section headers. */
.cw-body .cw-rails__more {
	/* ⚠️ A COLUMN, NOT `justify-content: center`. The row holds two children —
	   a "Showing 10 of 437" count and the button — so centring the ROW centres
	   the pair, leaving the button off by half the count's width. Measured 70px
	   off, then 68px after centring the row: the sibling was always going to
	   push it.

	   Stacking centres the button on its own line and keeps the count, which
	   is real information. CW-37 asks for the button to be centred; it now is,
	   at every width. */
	flex-direction: column;
	align-items: center;
	gap: .6rem;
	text-align: center;
}

.cw-body .cw-rails__all {
	margin-inline: auto;
}

/* =========================================================================
   §26  CW-77 / CW-78 — the listing card, measured against divinehindu

   Reference: divinehindu.in/collections/divine-jewellery on a 390px phone,
   measured 2026-09-08 rather than eyeballed from the screenshot.

   | element        | divinehindu | ours before |
   |----------------|-------------|-------------|
   | card width     | 180px       | 145px       |
   | title          | 12px        | 11px        |
   | price charged  | 16px        | 12px        |
   | % off          | 10px        | 8.5px       |
   | Choose options | 12px, r10, h36 | 11px, r4, h33 |

   🔴 THE CARDS ARE NOT THE SAME WIDTH, and that is why these are not their
   numbers exactly. We carry a 72px category side rail (CW-59) that divinehindu
   does not, so our card is 145px against their 180 — 81%. Copying a 16px price
   into a card 35px narrower is how text starts wrapping mid-rupee. The owner
   chose on 2026-09-08 to SCALE to our card rather than copy, so these sit
   between the two, and `ui:browser` measures every card for overflow.
   ========================================================================= */
.cw-body .cw-catwrap .cw-card__title,
.cw-body .cw-card__title {
	font-size: .71875rem;              /* 11 -> 11.5px */
}

/* ⚠️ THE PRICES ARE ALREADY RIGHT AND WERE NEARLY MADE WORSE. A first pass
   here targeted `.cw-money--now` / `.cw-money--was`, which the listing card
   does NOT use — those rules matched nothing. Measuring the card properly
   showed the charged price is `.font-semibold` at **15px**, against
   divinehindu's 16px, and the struck MRP is Bagisto's `.final-price` at 12px
   against their 13.5px. Both are already within a pixel of the scaled target,
   so scaling them would have made the price SMALLER. They are left alone.

   ⚠️ And note `final-price` is the STRUCK MRP, not the price charged. Bagisto's
   naming has caught a check in this repo once already. */

/* The discount flag is the one that was genuinely small.

   ⚠️ THE SELECTOR HAS TO BE THIS LONG. `.cw-body .cw-badge--sale` is (0,2,0)
   and loses to §20's `.cw-body .cw-catwrap .cw-card__pricerow .cw-badge--sale`
   at (0,4,0) inside the phone media query — the first attempt changed nothing
   and measured a flat 8.5px. Matching that specificity and coming later in the
   file is what wins, which is the arbitration rule this whole theme runs on. */
.cw-body .cw-catwrap .cw-card__pricerow .cw-badge--sale,
.cw-body .cw-card__pricerow .cw-badge--sale {
	font-size: .59375rem;              /* 8.5 -> 9.5px, theirs is 10px */
}

/* CW-78 — "Make Choose Option corner more curve". divinehindu's is 10px
   against our 4px, and their button is 36px tall to our 33px. Both copied
   exactly: the radius and height do not depend on the card being 180px wide. */
.cw-body .cw-card__cta > a,
.cw-body .cw-card__cta > button,
.cw-body .cw-catwrap .cw-card__cta > a,
.cw-body .cw-catwrap .cw-card__cta > button {
	border-radius: 10px;
	min-height: 36px;
	font-size: .75rem;                 /* 12px, matching theirs */
}

/* =========================================================================
   §27  CW-75 — the phone's Add to Cart / Buy Now, after divinehindu

   Measured on their product page at 390px, 2026-09-08:
     · both buttons on ONE row, ~178px each, 51px tall
     · pill radius (999px), not our 12px
     · Add to Cart is OUTLINED — transparent, maroon text, 2px border
     · Buy Now is filled
     · 15px / 600

   Ours were stacked, 310px wide, 50px tall, 12px radius, both filled.

   ⚠️ BUY NOW STAYS AMBER. divinehindu's is maroon; ours is the parent brand's
   accent and `ui:browser` asserts it. The owner chose on 2026-09-08 to copy
   the SHAPE and LAYOUT only and keep the colour, so the amber survives and the
   existing check stays valid. Do not "finish the job" by making it maroon.
   ========================================================================= */
@media (max-width: 900px) {
	/*
	 * 🔴 `!important` IS REQUIRED HERE AND SPECIFICITY IS NOT ENOUGH.
	 * brand.css:494 `.cw-body main .secondary-button` and elevation.css:447
	 * `.primary-button` both set background, border, radius and weight with
	 * `!important`. My first version was (1,2,1) — higher specificity than
	 * their (0,2,1) — and changed NOTHING but the height, because an important
	 * declaration beats a non-important one whatever the specificity. Only
	 * `min-height`, which nobody else marked important, took effect.
	 *
	 * So: important to enter the contest, and specificity to win it. The `form`
	 * id gives (1,2,1) against their (0,2,1). This is the same arbitration the
	 * whole theme runs on — CLAUDE.md records it, and it still caught me.
	 */
	.cw-body form#cw-pdp-form .primary-button,
	.cw-body form#cw-pdp-form .secondary-button {
		border-radius: 999px !important;
		min-height: 51px;
		font-size: .9375rem !important;
		font-weight: 600 !important;
	}

	/* ⚠️ ADD TO CART IS THE OUTLINED ONE, Buy Now the filled one — that is
	   divinehindu's hierarchy and it is deliberate: the filled button is the
	   one that skips the basket.
	   ⚠️ BUY NOW STAYS AMBER. Theirs is maroon; ours is the parent brand's
	   accent and `ui:browser` asserts it. The owner chose on 2026-09-08 to copy
	   the SHAPE and LAYOUT only. Do not "finish the job" by making it maroon. */
	.cw-body form#cw-pdp-form .secondary-button {
		background: transparent !important;
		color: var(--cw-color-maroon, #6C1322) !important;
		border: 2px solid var(--cw-color-maroon, #6C1322) !important;
	}

	/*
	 * One row, not two. Bagisto's wrapper carries `max-sm:flex-wrap` and each
	 * button `w-full`, which stacked them 310px wide.
	 *
	 * ⚠️ SELECTED BY WHAT IT CONTAINS, NOT BY ITS CLASSES. That div's classes
	 * are Tailwind utilities (`mt-8 flex max-w-[470px] gap-4 max-sm:flex-wrap`)
	 * — matching on those would break the moment Bagisto changes a utility.
	 * `:has()` names the thing structurally: the element holding both buttons.
	 */
	.cw-body form#cw-pdp-form div:has(> .primary-button):has(> .secondary-button) {
		flex-wrap: nowrap;
	}

	.cw-body form#cw-pdp-form div:has(> .primary-button):has(> .secondary-button) > .primary-button,
	.cw-body form#cw-pdp-form div:has(> .primary-button):has(> .secondary-button) > .secondary-button {
		flex: 1 1 0;
		width: auto !important;
		min-width: 0;
	}
}

/* =========================================================================
   §28  The product page's two fixed bars (owner, 2026-09-10)

   🔴 THIS REVERSES "ONE FIXED BOTTOM BAR PER SCREEN", WHICH IS A STANDING RULE
   IN CLAUDE.md, AND IT REVERSES THE OWNER'S OWN ANSWER FROM TWO DAYS EARLIER.
   On CW-76 (2026-09-08) they said the sticky menu belongs on "anything except
   individual product page". On 2026-09-10 they asked for it on the product page
   too, stacked under the buy bar, citing certifiedcrystal.com.

   ⚠️ WHAT THAT REFERENCE ACTUALLY DOES, measured on their mobile product page:
   two stacked fixed elements — a 96px promo strip at `bottom-16` above a 65px
   tab bar — and **no sticky buy bar at all**. So the STACKING is the precedent;
   the contents are ours. Worth knowing before someone "corrects" this to match
   them more closely.

   The cost is real and was put to the owner: 74 + 72 = 146px of an 844px phone,
   17% of the screen given to chrome. Decision taken with that in front of them.
   Recorded, not re-argued.
   ========================================================================= */
@media (max-width: 900px) {
	/* ⚠️ THE OVERRIDE HAS TO MATCH brand.css:5236's SPECIFICITY, which is
	   `.cw-body:has(.cw-buybar) .cw-tabbar` — (0,3,0) counting `:has()`'s
	   argument. An equal-specificity rule later in the cascade wins, and dh.css
	   loads last, which is the whole reason this file exists. */
	.cw-body:has(.cw-buybar) .cw-tabbar {
		display: grid;
	}

	/* The buy bar sits ON TOP of the tab bar, not over it. */
	.cw-body .cw-buybar {
		bottom: calc(var(--cw-tabbar-h, 72px) + env(safe-area-inset-bottom, 0px));
	}

	/* 🔴 AND THE PAGE HAS TO RESERVE BOTH, or the footer's last row sits under
	   them and cannot be tapped — which is exactly what happened when the tab
	   bar's height was guessed at 58px instead of measured at 72
	   (brand.css:5063). `ui:browser` asserts nothing overlaps the bottom bars. */
	.cw-body:has(.cw-buybar) {
		padding-bottom: calc(var(--cw-tabbar-h, 72px) + 74px + env(safe-area-inset-bottom, 0px));
	}
}

/* -------------------------------------------------------------------------
   The bar's two buttons (owner, 2026-09-10: "add Add to Cart and Buy Now
   button ... instead of just single Add to Basket button").
   ------------------------------------------------------------------------- */
.cw-body .cw-buybar__actions {
	display: flex;
	align-items: stretch;
	gap: 8px;
	min-width: 0;
}

/* 🔴 `display: flex` SILENTLY DEFEATS THE `hidden` ATTRIBUTE, AND THIS SHIPPED.
   `hidden` works through the user-agent stylesheet's `[hidden] { display: none }`,
   which ANY author `display` declaration outranks. So on a configurable product
   the bar rendered THREE controls at once — "Choose and add to basket", plus the
   Add to Cart / Buy Now pair that pdp.js had correctly marked hidden — and they
   squeezed each other until the product's name ran under them. That is what the
   owner photographed on 2026-09-10.

   ⚠️ THE CHECK I WROTE MISSED IT BECAUSE I ONLY TESTED A SIMPLE PRODUCT. On a
   simple product there is no choose-link and no hidden span, so two buttons fit
   and everything measured fine. `ui:browser` now counts the bar's visible
   controls on a CONFIGURABLE product too. */
.cw-body .cw-buybar__actions[hidden] {
	display: none;
}

/* 🔴 DO NOT PUT `flex: 1 1 0` HERE. That was the bug the owner photographed
   twice: brand.css gives `.cw-buybar__cta` `flex: none` with `white-space:
   nowrap` and `overflow: visible` on purpose, so the button is exactly as wide
   as its label. Forcing the two to share the width equally shrank them BELOW
   their text, and because the overflow is visible the label spilled out of the
   button — "Choose and add to basket" rendering as "Add to basket", and both
   buttons showing only their tails.

   ⚠️ THE BUTTONS KEEP THEIR CONTENT WIDTH AND THE NAME GIVES WAY. The name
   already truncates with an ellipsis (brand.css:929), which is the right thing
   to sacrifice — it is written in full at the top of the page, whereas a button
   whose label is half-hidden is unusable. */
.cw-body .cw-buybar__actions {
	flex: none;
}

/* 🔴 THE PRODUCT NAME COULD NOT SHRINK, SO THE BUTTONS PAINTED OVER IT.
   The name sits in an unnamed `<div>` inside `.cw-buybar__id`, and that div
   kept the default `min-width: auto` — which for a `white-space: nowrap` child
   is the FULL width of the name. So the div refused to shrink below the whole
   title, the ellipsis on `.cw-buybar__name` could never fire, and the buttons
   (correctly `flex: none`) overlapped it.

   ⚠️ `.cw-buybar__inner` AND `.cw-buybar__id` ALREADY HAD `min-width: 0` — the
   comment on the first one even explains this exact trap. It was missing on the
   one element between them that needed it, which is why the bar looked fine
   with one short button and broke with two.

   ⚠️ `min-width: 0` HAS TO BE ON EVERY FLEX ANCESTOR down to the truncating
   element. One gap in the chain is enough to defeat the whole thing. */
.cw-body .cw-buybar__id {
	flex: 1 1 auto;
	min-width: 0;
}

.cw-body .cw-buybar__id > div {
	min-width: 0;
	overflow: hidden;
}

/* ⚠️ AMBER, matching the buy box's Buy Now — CW-75 kept that accent
   deliberately when divinehindu's equivalent is maroon. The two Buy Nows on one
   page must not be different colours. */
.cw-body .cw-buybar__cta--now {
	background: var(--cw-color-amber, #FBBF24);
	color: var(--cw-color-ink, #35251D);
	border-color: var(--cw-color-amber, #FBBF24);
}

/* The way back out of checkout — see checkout/cw-back.blade.php. */
.cw-body .cw-checkoutback {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 12px;
	padding: 8px 4px;
	color: var(--cw-color-maroon, #6C1322);
	font-size: .875rem;
	font-weight: 600;
	text-decoration: none;
	/* ⚠️ 44px of tappable height on a phone, per the WCAG target audit that
	   found the footer links at 17-19px. */
	min-height: 44px;
}

.cw-body .cw-checkoutback svg {
	width: 16px;
	height: 16px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.cw-body .cw-checkoutback:hover { text-decoration: underline; }

/* =========================================================================
   §29  The full-screen image viewer's close button

   🔴 REPORTED 2026-09-10: opening a product image leaves you stuck.
   Measured: the viewer DOES have a close control — Bagisto's
   `<span class="icon-cancel">` at the top right, 30x30 and technically
   "visible" — but it is an ICON-FONT GLYPH with no text, and its `::before`
   content resolves to an empty string in the `bagisto-shop` face. So it renders
   as nothing: a 30x30 invisible tap target in the corner of a full-screen
   photograph. A shopper has no way of knowing it is there.

   ⚠️ THE FIX IS TO DRAW THE MARK, NOT TO LOAD THE FONT. Pulling in an icon
   webfont for one glyph costs a request and a render-blocking dependency, and
   this theme deliberately draws its own icons everywhere else.

   ⚠️ AND IT IS SIZED FOR A THUMB. 30x30 is below the 44px WCAG target the
   footer audit already flagged, and this one sits over a photograph where a
   miss means an accidental zoom instead.
   ========================================================================= */
/* 🔴 AND THE VIEWER SAT UNDERNEATH OUR OWN CHROME, WHICH IS THE REAL REASON
   IT FELT LIKE A TRAP. Bagisto gives the full-screen container `z-10` and its
   close button `z-1000` — but that 1000 is INSIDE the container's stacking
   context, so it can never rise above the container's own 10. Our header is
   z-50 and the tab bar z-60, both of which therefore paint over the entire
   viewer.

   Measured: `document.elementFromPoint()` at the close button's own coordinates
   returned `cw-header__inner`. A shopper tapping the X was tapping the cart
   icon. That is also why the screenshot of the "full-screen" image showed our
   header sitting across the top of it.

   ⚠️ RAISE THE CONTAINER, NOT THE BUTTON. Bumping `.icon-cancel` alone changes
   nothing for the same stacking-context reason that broke it.

   ⚠️ SELECTED STRUCTURALLY, on the element that holds the close control, rather
   than by Bagisto's Tailwind utilities (`.fixed.inset-0.z-10`) — those are
   theirs to change on any upgrade. */
.cw-body div:has(> .icon-cancel) {
	z-index: 200;
}

.cw-body .icon-cancel {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border-radius: 999px;
	/* Dark disc so the mark reads over any photograph, light or dark. */
	background: rgba(0, 0, 0, .55);
	backdrop-filter: blur(2px);
	color: #FFFFFF;
	font-size: 0;                    /* kills the empty glyph's line box */
}

/* The X itself, drawn rather than fetched. */
.cw-body .icon-cancel::before,
.cw-body .icon-cancel::after {
	content: "";
	grid-area: 1 / 1;
	width: 18px;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
}

.cw-body .icon-cancel::before { transform: rotate(45deg); }
.cw-body .icon-cancel::after  { transform: rotate(-45deg); }

.cw-body .icon-cancel:hover { background: rgba(0, 0, 0, .78); }

/* =========================================================================
   CW-83 (redo, 2026-09-14) — the footer, laid out properly

   🔴 WHAT THE OWNER SAW: brand, Shop and Jewellery on row one; Company,
   Policies and a lone copyright line floating on row two, with a 700px empty
   hole under the blurb. Two causes, both mine:
     1. the markup never closed `.cw-footer__inner`, so the copyright became a
        grid item;
     2. the grid was still `1.6fr + 2 x 1fr` — three columns, built for the
        old footer's two link columns — and CW-83 added four without touching
        it.
   On a phone the same footer was one column 1,235px tall.

   THE SHAPE NOW
     >= 1100px  brand | Shop | Jewellery | Company | Policies   (one row)
     760-1099   brand across the top, four link columns under it
     < 760      brand across the top, links in a 2 x 2 grid
     all        a divided bottom bar: copyright left, credit right
                (stacked and centred on a phone)

   ⚠️ Every rule is `.cw-body .cw-footer ...` — (0,2,x). The footer is styled
   in FOUR older sheets: components.css (grid), storefront.css (gold links),
   brand.css (frame padding) and this file's own 24px tap-target rule, which is
   kept. A bare `.cw-footer__inner` here would lose to brand.css.
   ========================================================================= */

.cw-body .cw-footer {
	padding: clamp(40px, 6vw, 64px) 0 0;
}

.cw-body .cw-footer__inner {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) repeat(4, minmax(0, 1fr));
	column-gap: clamp(24px, 3vw, 48px);
	row-gap: 36px;
	padding-bottom: clamp(36px, 5vw, 56px);
	align-items: start;
}

/* ---- brand column ---- */

/* ⚠️ `a.` IS LOAD-BEARING. This file's own tap-target rule,
   `.cw-body .cw-footer a { display: inline-block }`, is (0,2,1); the bare class
   form of this selector was (0,2,0) and lost — the logo stacked above the
   wordmark instead of beside it. */
.cw-body .cw-footer a.cw-footer__mark {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	min-height: 0;
	line-height: 1;
	color: #FDF6EC;
}

.cw-body .cw-footer__mark img {
	width: 56px;
	height: 56px;
	border-radius: 50%;
	flex: none;
	box-shadow: 0 0 0 2px rgba(200, 154, 60, .55);
}

.cw-body .cw-footer .cw-foot-title {
	margin: 0;
	font-size: 22px;
	line-height: 1.2;
	font-weight: 600;
	color: #FDF6EC;
}

.cw-body .cw-footer__blurb {
	margin: 16px 0 20px;
	max-width: 30rem;
	font-size: 14px;
	line-height: 1.6;
	color: rgba(253, 246, 236, .72);
}

.cw-body .cw-footer .cw-footer__contact {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-height: 40px;
	padding: 0 16px;
	line-height: 1;
	font-size: 14px;
	font-weight: 500;
	color: #FDF6EC;
	border: 1px solid rgba(253, 246, 236, .22);
	border-radius: 999px;
	transition: border-color .15s ease, color .15s ease;
}

.cw-body .cw-footer .cw-footer__contact svg { color: #4ADE80; flex: none; }

.cw-body .cw-footer .cw-footer__contact:hover {
	color: var(--cw-color-gold);
	border-color: rgba(200, 154, 60, .7);
	text-decoration: none;
}

/* ---- link columns ---- */

.cw-body .cw-footer .cw-foot-h {
	margin: 0 0 14px;
	font-size: 12px;
	line-height: 1.4;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--cw-color-gold);
}

.cw-body .cw-footer__col ul {
	gap: 4px;
	font-size: 14px;
}

/* ⚠️ Links in CREAM, headings in GOLD. Everything was gold, so nothing read
   as a heading and twenty-two links shouted at the same volume. */
.cw-body .cw-footer__col a {
	color: rgba(253, 246, 236, .78);
	transition: color .15s ease;
}

.cw-body .cw-footer__col a:hover {
	color: var(--cw-color-gold);
	text-decoration: none;
}

/* ---- bottom bar ---- */

.cw-body .cw-footer__bottom {
	position: relative;
	max-width: var(--cw-wide);
	margin-inline: auto;
	padding: 20px var(--cw-space-30) 24px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 8px 24px;
	font-size: 13px;
	color: rgba(253, 246, 236, .6);
}

/* ⚠️ The rule is a pseudo-element, not a border: a border on this box would
   run into the 24px gutters and stop 24px wider than every column above it. */
.cw-body .cw-footer__bottom::before {
	content: "";
	position: absolute;
	top: 0;
	left: var(--cw-space-30);
	right: var(--cw-space-30);
	height: 1px;
	background: rgba(253, 246, 236, .14);
}

.cw-body .cw-footer__legal,
.cw-body .cw-footer__credit {
	margin: 0;
	max-width: none;
	text-align: left;
	font-size: inherit;
	color: inherit;
}

.cw-body .cw-footer__credit a {
	color: rgba(253, 246, 236, .82);
	border-bottom: 1px solid rgba(200, 154, 60, .5);
}

.cw-body .cw-footer__credit a:hover { color: var(--cw-color-gold); }

/* ---- tablet: brand on its own row, four columns under it ---- */

@media (max-width: 1099px) {
	.cw-body .cw-footer__inner {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.cw-body .cw-footer__brand {
		grid-column: 1 / -1;
		display: grid;
		grid-template-columns: auto minmax(0, 1fr) auto;
		align-items: center;
		column-gap: 24px;
	}

	.cw-body .cw-footer__blurb { margin: 0; }
}

/* ---- phone: brand stacked, links in a 2 x 2 grid ---- */

@media (max-width: 759px) {
	.cw-body .cw-footer__inner {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 20px;
		row-gap: 32px;
	}

	.cw-body .cw-footer__brand {
		display: block;
		padding-bottom: 28px;
		border-bottom: 1px solid rgba(253, 246, 236, .12);
	}

	.cw-body .cw-footer__blurb { margin: 14px 0 18px; }

	/* 24px is the WCAG floor; on a phone these are thumbs, not cursors. */
	.cw-body .cw-footer__col a {
		min-height: 32px;
		line-height: 32px;
	}

	.cw-body .cw-footer__col ul { gap: 0; }

	.cw-body .cw-footer__bottom {
		flex-direction: column;
		justify-content: center;
		text-align: center;
		padding-block: 18px 22px;
	}

	.cw-body .cw-footer__legal,
	.cw-body .cw-footer__credit { text-align: center; }
}

/* =========================================================================
   PRODUCT PAGE — divinehindu's buy column (owner, 2026-09-14)

   "Make the product page similar to divinehindu.in." Scope agreed with the
   owner the same day: EVERYTHING BELOW THE PHOTOS, plus "Pair it with".
   Explicitly NOT changed, by the owner's choice: the stacked sticky buy bar +
   tab bar, the chips row, the sold line, the countdown, the inline buttons and
   Compare. No certificate card under the photos — there is nothing to download.

   SIZES ARE MEASURED off divinehindu's live page at 390px, not eyeballed:
     rating   stars 14px #F76A00 · value 11.5/700 · count 12px underlined
     price    charged 26/800 #111 · struck 16/500 #98928A · "View Offers" 13/700
     OFF pill #111 on white, 13/800, radius 9, padding 6 11, on its own line
     tax      12px #8A8378
     qty      label 16/600 · maroon segmented stepper
     add-on   1px gold border, radius 12, #FFFDF6, title 14/700
     assure   #FDF6EC, 1px #EFE3CD, radius 10
     offers   heading 16/800 · copy button #F3EAD9 / #D9C7A8, radius 10
     pair     heading 22/700 centred · 102px thumbs · add button radius 12
   COLOURS ARE OURS. Their maroon is #8B1E2D; ours is the parent brand's
   #6C1322 (a settled decision), and Buy Now stays amber as the owner chose.

   ⚠️ SCOPED TO `.cw-buycol`, a class added to the details column in our own
   products/view.blade.php. The price, rating and quantity components are
   SHARED with the listing cards and the cart drawer; a bare `.cw-priceline` or
   `[class*=quantity]` rule here would restyle those too.
   ========================================================================= */

/* ---- 0. the column sat 24px inboard of the photo above it ----

   MEASURED at 390px: photo edge x=16, title x=40. The `.container` carries the
   site-wide 24px gutter (brand.css frame rule) AND Bagisto's details column
   adds its own `max-sm:px-4` inside it. The gallery bleeds to 16 on purpose
   (the divinehindu clone), so the product block read as two misaligned columns.
   divinehindu puts photo and text on the same 16px edge; so does this. */
@media (max-width: 639px) {
	.cw-body main .cw-buycol {
		padding-inline: 0;
		margin-inline: -8px;
		width: calc(100% + 16px);
		max-width: none;
	}
}

/* ---- 1. rating row ---- */

.cw-body main .cw-buycol .cw-rating {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px 10px;
	margin: 10px 0 12px;
}

.cw-body main .cw-buycol .cw-rating__stars {
	position: relative;
	display: inline-block;
	font-size: 15px;
	line-height: 1;
	letter-spacing: 1px;
	color: #E6DCCB;
	white-space: nowrap;
}

/* The coloured copy, clipped to the average. */
.cw-body main .cw-buycol .cw-rating__stars::before {
	content: "★★★★★";
	position: absolute;
	inset: 0 auto 0 0;
	width: var(--cw-fill, 100%);
	overflow: hidden;
	color: #F76A00;
	z-index: 1;
}

.cw-body main .cw-buycol .cw-rating__value {
	font-size: 12px;
	font-weight: 700;
	color: var(--cw-color-ink);
}

.cw-body main .cw-buycol a.cw-rating__count {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	font-size: 12px;
	font-weight: 400;
	color: #1A1A1A;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.cw-body main .cw-buycol .cw-sold {
	display: block;
	margin: 0 0 12px;
}

/* ---- 2. price row ----

   ⚠️ THE CHILDREN ARE WHATEVER THE PARSER LEFT. Bagisto nests <p> in <p>, so
   inside `.cw-priceline` there are two EMPTY paragraphs around the prices. They
   are hidden, and the prices are addressed by the one hook every product type
   shares: the struck price always carries `line-through`, the charged price
   always carries `font-semibold` without it. `order` does the rearranging, so
   no markup depends on the broken nesting. */
.cw-body main .cw-buycol .cw-priceline {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	/* ⚠️ NO ROW GAP. The zero-height break is a row of its own, so an 8px row
	   gap was paid twice above the OFF pill — 16px where theirs is 10. The pill
	   carries its own top margin instead. */
	gap: 0 12px;
	margin: 14px 0 0;
}

.cw-body main .cw-buycol .cw-priceline > p.flex { display: contents; }

/* ⚠️ TWO SHAPES OF THE SAME ROW. On a SIMPLE product the server HTML nests
   <p> in <p>, the parser splits it, and the prices arrive as direct children
   beside an empty wrapper. On a CONFIGURABLE product Vue re-renders the price
   (it changes with the chosen variant), and Vue CAN nest <p> in <p> — so the
   prices stay INSIDE the wrapper, which then sat as one 327px flex item: "As
   low as" inline, the MRP wrapped onto two lines, View Offers below it.
   `display: contents` on the wrapper makes its children flex items of this
   row either way, so one set of rules lays out both. */
.cw-body main .cw-buycol .cw-priceline > p:empty { display: none; }

.cw-body main .cw-buycol .cw-priceline .price-label {
	order: 0;
	flex-basis: 100%;
	margin: 0;
	font-size: 12px;
	font-weight: 500;
	color: #8A8378;
}

.cw-body main .cw-buycol .cw-priceline p.font-semibold:not(.line-through) {
	order: 1;
	margin: 0;
	font-size: 26px;
	line-height: 1.15;
	font-weight: 800;
	color: #111111;
}

.cw-body main .cw-buycol .cw-priceline .line-through {
	order: 2;
	margin: 0;
	font-size: 16px;
	line-height: 1.15;
	font-weight: 500;
	color: #98928A;
}

/* "MRP" is theirs, and it is what the struck figure actually is — the
   fabricated-but-recorded MRP (PDP-REBUILD §2). */
.cw-body main .cw-buycol .cw-priceline .line-through::before {
	content: "MRP ";
}

.cw-body main .cw-buycol .cw-priceline a.cw-viewoffers {
	order: 3;
	margin-left: auto;
	align-self: center;
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	font-size: 13px;
	font-weight: 700;
	color: var(--cw-color-maroon);
	text-decoration: underline;
	text-underline-offset: 3px;
	white-space: nowrap;
}

.cw-body main .cw-buycol .cw-priceline .cw-pricebreak {
	order: 4;
	flex-basis: 100%;
	height: 0;
}

.cw-body main .cw-buycol .cw-priceline .cw-save {
	order: 5;
	display: inline-flex;
	align-items: center;
	margin: 10px 0 0;
	padding: 6px 11px;
	border: 0;
	border-radius: 9px;
	background: #111111;
	color: #FFFFFF;
	font-size: 13px;
	line-height: 1.4;
	font-weight: 800;
	letter-spacing: normal;
}

.cw-body main .cw-buycol .cw-taxnote {
	margin: 6px 0 0;
	font-size: 12px;
	line-height: 1.5;
	color: #8A8378;
}

/* ---- 3. quantity ---- */

/* ⚠️ PHONE ONLY. Above 640px brand.css floats this row at 58% with Buy Now
   beside it at 42% — about 342px for label, stepper and Add to Cart. With the
   label in it the stepper was crushed to a sliver and its "+" clipped. The
   label is divinehindu's MOBILE treatment, and on a phone this row wraps. */
.cw-body main .cw-buycol .cw-qtylabel { display: none; }

@media (max-width: 640px) {
	.cw-body main .cw-buycol .cw-qtylabel { display: inline; }
}

.cw-body main .cw-buycol .cw-qtylabel {
	align-self: center;
	font-size: 16px;
	line-height: 24px;
	font-weight: 600;
	color: #1A1A1A;
}

/* ⚠️ `:has(> .icon-plus)` BECAUSE THE STEPPER HAS NO CLASS OF ITS OWN. The
   Vue component's root <div> takes whatever utilities the caller passes, and
   the same component draws the cart drawer's stepper. Matching on its direct
   child, inside `.cw-buycol`, reaches this one only. */
.cw-body main .cw-buycol div:has(> .icon-plus) {
	/* Never shrink: in the desktop float row it is the flex item that gave way. */
	flex: none;
	display: inline-flex;
	align-items: stretch;
	gap: 0;
	height: 40px;
	padding: 0;
	border: 1px solid var(--cw-color-maroon);
	border-radius: 999px;
	overflow: hidden;
	background: #FFFFFF;
}

.cw-body main .cw-buycol div:has(> .icon-plus) > .icon-minus,
.cw-body main .cw-buycol div:has(> .icon-plus) > .icon-plus,
.cw-body main .cw-buycol div:has(> .icon-plus) > .icon-bin {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	margin: 0;
	font-size: 20px;
	background: var(--cw-color-maroon);
	color: #FFFFFF;
}

.cw-body main .cw-buycol div:has(> .icon-plus) > p {
	display: flex;
	align-items: center;
	justify-content: center;
	width: auto;
	min-width: 46px;
	margin: 0;
	font-size: 16px;
	font-weight: 700;
	color: var(--cw-color-maroon);
}

/* ---- 4. the certificate add-on, as divinehindu's Siddhi card ---- */

.cw-body main .cw-buycol .cw-cert {
	align-items: center;
	gap: 12px;
	padding: 12px 14px;
	border: 1px solid var(--cw-color-gold);
	border-radius: 12px;
	background: #FFFDF6;
}

/* ⚠️ THE ALL-CAPS WAS INHERITED, not declared on the card: a generic label
   rule upper-cases and tracks every <label> in the buy box. Reset here rather
   than there, because the variant labels rely on it. */
.cw-body main .cw-buycol .cw-cert,
.cw-body main .cw-buycol .cw-cert * {
	text-transform: none;
	letter-spacing: normal;
}

.cw-body main .cw-buycol .cw-cert__box {
	width: 22px;
	height: 22px;
	margin: 0;
}

.cw-body main .cw-buycol .cw-cert__title {
	font-size: 14px;
	line-height: 1.5;
	font-weight: 700;
	color: var(--cw-color-maroon);
}

.cw-body main .cw-buycol .cw-cert__note {
	font-weight: 400;
	font-size: 13px;
	line-height: 1.45;
	color: #7A6F60;
}

.cw-body main .cw-buycol .cw-cert:has(.cw-cert__box:checked) {
	border-color: var(--cw-color-maroon);
	background: #FFF7E6;
}

/* ---- 5. the assurance list, as one compact box ---- */

.cw-body main .cw-buycol .cw-assure {
	margin: 18px 0 0;
	padding: 14px;
	max-width: none;
	border: 1px solid #EFE3CD;
	border-radius: 10px;
	background: #FDF6EC;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 12px 14px;
}

.cw-body main .cw-buycol .cw-assure li {
	grid-template-columns: 20px 1fr;
	gap: 8px;
	font-size: 12px;
	line-height: 1.35;
}

.cw-body main .cw-buycol .cw-assure svg {
	width: 18px;
	height: 18px;
}

.cw-body main .cw-buycol .cw-assure strong {
	font-size: 13px;
	font-weight: 700;
	line-height: 1.35;
}

/* brand.css drops this to ONE column under 420px, which is exactly the phone
   width divinehindu's box is designed for. Two columns hold at 360px. */
@media (max-width: 420px) {
	.cw-body main .cw-buycol .cw-assure { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- 6. offers ---- */

/* brand.css caps offers and the pincode card at 470px; every other card in
   this column (add-on, assurance, Pair it with) runs the full width, so on
   desktop these two stopped 120px short of the rest. */
.cw-body main .cw-buycol .cw-offers,
.cw-body main .cw-buycol .cw-deliver { max-width: none; }

.cw-body main .cw-buycol .cw-offers { margin-top: 22px; }

.cw-body main .cw-buycol .cw-offers__h {
	margin: 0 0 10px;
	font-family: var(--cw-font-body);
	font-size: 16px;
	line-height: 1.5;
	font-weight: 800;
	color: #1A1A1A;
}

.cw-body main .cw-buycol .cw-offer {
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 12px;
	padding: 12px 14px;
	border: 1px solid #E7D9C4;
	border-style: solid;
	border-radius: 12px;
	background: #FFFFFF;
}

.cw-body main .cw-buycol button.cw-offer__code {
	grid-column: auto;
	justify-self: end;
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1px;
	min-width: 90px;
	min-height: 44px;
	padding: 6px 12px;
	border: 1px solid #D9C7A8;
	border-radius: 10px;
	background: #F3EAD9;
	color: var(--cw-color-maroon);
	font-family: var(--cw-font-body);
	cursor: pointer;
}

.cw-body main .cw-buycol .cw-offer__codetext {
	font-size: 12px;
	font-weight: 800;
	letter-spacing: .04em;
}

.cw-body main .cw-buycol .cw-offer__copy {
	font-size: 11px;
	font-weight: 600;
	color: #7A6F60;
}

.cw-body main .cw-buycol button.cw-offer__code.is-copied .cw-offer__copy { color: #047857; }

.cw-body main .cw-buycol .cw-offer__auto {
	grid-column: auto;
	justify-self: end;
	/* It was as wide as its text and squeezed the offer it describes onto
	   three lines at 390px. */
	max-width: 92px;
	/* brand.css sets `nowrap`, which is why max-width alone did nothing and
	   the text ran out past the card's border. */
	white-space: normal;
	font-size: 12px;
	line-height: 1.3;
	text-align: right;
}

/* brand.css stacks the code under the text below 620px; there is room for it
   on the right at 360px, which is where divinehindu keeps it. */
@media (max-width: 620px) {
	.cw-body main .cw-buycol .cw-offer { grid-template-columns: auto minmax(0, 1fr) auto; }
	.cw-body main .cw-buycol .cw-offer__code,
	.cw-body main .cw-buycol .cw-offer__auto { grid-column: auto; justify-self: end; }
}

/* ---- 7. delivery check — same card language ---- */

.cw-body main .cw-buycol .cw-deliver {
	border-radius: 12px;
	border-color: #E7D9C4;
}

/* ---- 8. Pair it with ---- */

.cw-body main .cw-buycol .cw-pair {
	margin: 28px 0 0;
	padding: 22px 16px 8px;
	border-top: 1px solid var(--cw-color-line);
}

.cw-body main .cw-buycol .cw-pair__h {
	margin: 0 0 12px;
	text-align: center;
	font-family: var(--cw-font-heading);
	font-size: 22px;
	line-height: 1.2;
	font-weight: 700;
	color: #1A1A1A;
}

.cw-body main .cw-buycol .cw-pair__note {
	margin: 0 0 16px;
	padding: 10px 14px;
	border: 1px solid var(--cw-color-gold);
	border-radius: 10px;
	background: #FFFDF6;
	text-align: center;
	font-size: 13.5px;
	line-height: 1.45;
	font-weight: 600;
	color: #5A431A;
}

/* A scrolling strip, as theirs: four items at 102px plus separators is wider
   than a 358px phone, and wrapping them would break the "a + b + c" reading. */
.cw-body main .cw-buycol .cw-pair__strip {
	display: flex;
	align-items: center;
	gap: 8px;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	padding: 2px 2px 8px;
	margin: 0 0 14px;
	scrollbar-width: thin;
}

.cw-body main .cw-buycol label.cw-pair__thumb {
	position: relative;
	flex: 0 0 auto;
	width: 102px;
	height: 102px;
	border: 1px solid #EFE3CD;
	border-radius: 10px;
	overflow: hidden;
	background: #FFFFFF;
	scroll-snap-align: start;
	cursor: pointer;
	transition: opacity .15s ease, filter .15s ease;
}

/* ⚠️ COVER, NOT CONTAIN. The catalogue's photographs are square-ish but not
   square, and `contain` left the ring floating in a black band with white
   above and below it. */
.cw-body main .cw-buycol label.cw-pair__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The tick: filled maroon with a check when the item is in, an empty white
   square when it is out. Drawn, not an icon font — it must survive a font
   that has not loaded. */
.cw-body main .cw-buycol .cw-pair__tick {
	position: absolute;
	top: 6px;
	right: 6px;
	width: 22px;
	height: 22px;
	border: 2px solid var(--cw-color-maroon);
	border-radius: 7px;
	background: var(--cw-color-maroon);
}

.cw-body main .cw-buycol .cw-pair__tick::after {
	content: "";
	position: absolute;
	left: 6px;
	top: 2px;
	width: 6px;
	height: 11px;
	border: solid #FFFFFF;
	border-width: 0 2.5px 2.5px 0;
	transform: rotate(45deg);
}

.cw-body main .cw-buycol label.cw-pair__thumb.is-off { opacity: .55; filter: grayscale(.4); }
.cw-body main .cw-buycol label.cw-pair__thumb.is-off .cw-pair__tick { background: #FFFFFF; }
.cw-body main .cw-buycol label.cw-pair__thumb.is-off .cw-pair__tick::after { display: none; }

.cw-body main .cw-buycol .cw-pair__plus {
	flex: 0 0 auto;
	font-size: 20px;
	font-weight: 700;
	color: var(--cw-color-maroon);
}

.cw-body main .cw-buycol .cw-pair__total {
	display: flex;
	align-items: baseline;
	justify-content: center;
	flex-wrap: wrap;
	gap: 4px 10px;
	margin: 0 0 12px;
}

.cw-body main .cw-buycol .cw-pair__label {
	font-size: 17px;
	font-weight: 600;
	color: #333333;
}

.cw-body main .cw-buycol .cw-pair__mrp {
	font-size: 14px;
	color: #A49781;
}

.cw-body main .cw-buycol .cw-pair__now {
	font-size: 22px;
	font-weight: 800;
	color: var(--cw-color-maroon);
}

.cw-body main .cw-buycol button.cw-pair__add {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 50px;
	margin: 0 0 16px;
	padding: 0 18px;
	border: 0;
	border-radius: 12px;
	background: var(--cw-color-maroon);
	color: #FFFFFF;
	font-family: var(--cw-font-body);
	font-size: 15px;
	font-weight: 800;
	letter-spacing: .06em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background .15s ease, opacity .15s ease;
}

.cw-body main .cw-buycol button.cw-pair__add:hover { background: var(--cw-color-maroon-dark, #4F0E19); }
.cw-body main .cw-buycol button.cw-pair__add:disabled { opacity: .45; cursor: not-allowed; }
.cw-body main .cw-buycol button.cw-pair__add.is-busy { opacity: .8; cursor: progress; }

.cw-body main .cw-buycol .cw-pair__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 12px;
}

.cw-body main .cw-buycol .cw-pair__row {
	display: flex;
	align-items: flex-start;
	gap: 11px;
}

.cw-body main .cw-buycol .cw-pair__box {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	margin: 2px 0 0;
	accent-color: var(--cw-color-maroon);
	cursor: pointer;
}

.cw-body main .cw-buycol label.cw-pair__text,
.cw-body main .cw-buycol label.cw-pair__text * {
	text-transform: none;
	letter-spacing: normal;
}

.cw-body main .cw-buycol label.cw-pair__text {
	display: block;
	min-width: 0;
	font-size: 14.5px;
	line-height: 1.45;
	font-weight: 400;
	color: #1A1A1A;
	cursor: pointer;
}

.cw-body main .cw-buycol .cw-pair__this {
	display: inline-block;
	margin-right: 6px;
	padding: 1px 7px;
	border-radius: 6px;
	background: #F6E4E4;
	color: var(--cw-color-maroon);
	font-size: 11px;
	font-weight: 800;
	text-transform: uppercase;
	vertical-align: 1px;
}

/* ⚠️ (0,4,2) ON PURPOSE. The case reset above, `label.cw-pair__text *`, is
   (0,3,2) and beat the plain `.cw-pair__this` rule — the pill read "This item". */
.cw-body main .cw-buycol label.cw-pair__text .cw-pair__this { text-transform: uppercase; }

.cw-body main .cw-buycol a.cw-pair__name {
	color: #1A1A1A;
	text-decoration: none;
}

.cw-body main .cw-buycol a.cw-pair__name:hover { text-decoration: underline; }

.cw-body main .cw-buycol .cw-pair__prices {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
	margin-left: 6px;
	white-space: nowrap;
}

.cw-body main .cw-buycol .cw-pair__prices s {
	font-size: 13px;
	color: #A49781;
}

.cw-body main .cw-buycol .cw-pair__prices b {
	font-size: 15px;
	font-weight: 800;
	color: var(--cw-color-maroon);
}

@media (prefers-reduced-motion: reduce) {
	.cw-body main .cw-buycol label.cw-pair__thumb,
	.cw-body main .cw-buycol button.cw-pair__add { transition: none; }
}

/* =========================================================================
   CW-49 — Shiprocket Checkout: the "opening" veil and the thank-you page
   ========================================================================= */

/* Between the tap and Shiprocket's popup there is a token request and, the
   first time, their script loading — up to a couple of seconds on a phone. A
   tap that visibly does nothing gets tapped again. */
.cw-sr-wait {
	position: fixed;
	inset: 0;
	z-index: 2000;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	background: rgba(37, 19, 12, .45);
	color: #FFFFFF;
	font-size: 15px;
	font-weight: 600;
}

.cw-sr-wait[hidden] { display: none; }

.cw-sr-wait__spin {
	width: 22px;
	height: 22px;
	border: 3px solid rgba(255, 255, 255, .35);
	border-top-color: #FFFFFF;
	border-radius: 50%;
	animation: cw-sr-spin .8s linear infinite;
}

@keyframes cw-sr-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
	.cw-sr-wait__spin { animation: none; }
}

.cw-body .cw-srthanks {
	max-width: 560px;
	margin: 48px auto;
	padding: 28px 24px;
	border: 1px solid var(--cw-color-line);
	border-radius: 14px;
	background: #FFFFFF;
	text-align: center;
}

.cw-body .cw-srthanks__h {
	margin: 0 0 12px;
	font-family: var(--cw-font-heading);
	font-size: 24px;
	line-height: 1.25;
	color: #1A1A1A;
}

.cw-body .cw-srthanks__p {
	margin: 0 0 12px;
	font-size: 15px;
	line-height: 1.55;
	color: var(--cw-color-muted);
}

.cw-body .cw-srthanks__ref {
	margin: 16px 0;
	font-size: 14px;
	color: #1A1A1A;
}

.cw-body a.cw-srthanks__cta {
	display: inline-flex;
	align-items: center;
	min-height: 46px;
	margin-top: 8px;
	padding: 0 22px;
	border-radius: 999px;
	background: var(--cw-color-maroon);
	color: #FFFFFF;
	font-weight: 700;
	text-decoration: none;
}
