/*
 * OSTADEEZ — scheme-driven surfaces.
 *
 * THE STANDARD: a surface belongs here when it is drawn by a PLUGIN that ships its own literal
 * colours and therefore cannot follow the token swap on its own. Everything in this file does one
 * thing — hand that surface a `--ostz-*` token instead of the colour it shipped with.
 *
 * Nothing here invents a colour. If a rule below contains a hex value, it is wrong.
 */

/* ---------------------------------------------------------------- the toggle */

.ostz-scheme {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 1px solid var(--ostz-line-strong);
	border-radius: 10px;
	background: transparent;
	color: var(--ostz-text-dim);
	font-size: var(--ostz-text-md);
	line-height: 1;
	cursor: pointer;
	transition: color .18s ease, border-color .18s ease;
}

.ostz-scheme:hover {
	color: var(--ostz-accent);
	border-color: var(--ostz-accent);
}

/* One glyph per scheme: the icon shows what a click will GIVE you, not where you are. */
.ostz-scheme-sun {
	display: none;
}

.ostz-scheme-moon {
	display: inline;
}

[data-theme='light'] .ostz-scheme-sun {
	display: inline;
}

[data-theme='light'] .ostz-scheme-moon {
	display: none;
}

/* ---------------------------------------------------------------- category chips
 * ⚠ THE CHIP'S COLOUR IS NOT HERE ANY MORE, and the reason it ever was is worth keeping.
 *
 * `.ostz a { color: inherit }` in the main sheet scored 0-1-1 and therefore BEAT `.ostz-chip` at
 * 0-1-0, so the chips never used their own colour token — they inherited, and in light mode read
 * as near-white text on a near-white surface. The workaround was to re-declare the colour HERE at
 * 0-2-0, which fixed the symptom and split one component across two files.
 *
 * The main sheet's anchor rule is `:where(.ostz) a` now — zero specificity — so the component
 * simply wins, and modules/ostadeez-m-chip.css carries every chip declaration including the
 * `text-DIM, not text-faint` decision the count needed (measured 4.16:1 on its own lifted pill,
 * where the faint token passes on the page but not on the chip).
 */

/* ---------------------------------------------------------------- the filter rail
   The search plugin paints its sidebar in its own stylesheet, which is why the rail stayed light
   on a dark page. These hand it the tokens; the values still live in one place.

   ⚠ THE CLASS NAMES BELOW WERE READ OFF THE RENDERED PAGE, not carried over. The previous
   version of this block styled `dms-sidebar-box__body`, `dms-widget` and `dm-search-widget` —
   names this plugin version does not emit — so it painted nothing at all while looking correct
   in the file. Measured result before the fix: accordion titles at 1.14 contrast, i.e. invisible,
   and white toggle pills. A rule that matches nothing fails silently and forever. */

.ostz-filters .dms-sidebar-box,
.ostz-filters .dms-sidebar-box__header,
.ostz-filters .dms-sidebar-box__plain,
.ostz-filters .dms-card,
.ostz-filters .dms-card__body {
	background: transparent;
	color: var(--ostz-text);
	border-color: var(--ostz-line);
}

/* The rail is already a panel; a second panel inside it is a box in a box. */
.ostz-filters .dms-sidebar-box {
	border: 0;
	padding: 0;
	box-shadow: none;
}

/* The plugin prints its own «فیلترها» heading, and the rail header above it says the same word.
   One heading per thing. */
.ostz-filters .dms-sidebar-box__header {
	display: none;
}

/* Same duplication one level down: the card repeats the accordion's own title. */
.ostz-filters .dms-card__header {
	display: none;
}

.ostz-filters .dms-accordion-item {
	border: 0;
	border-block-end: 1px solid var(--ostz-line);
	background: transparent;
}

.ostz-filters .dms-accordion-item:last-child {
	border-block-end: 0;
}

.ostz-filters .dms-accordion-item__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
	min-height: 44px;
	padding: 8px 4px;
	border: 0;
	background: transparent;
	color: var(--ostz-text);
	font-family: inherit;
	font-size: var(--ostz-text-sm);
	font-weight: var(--ostz-weight-bold);
	cursor: pointer;
}

.ostz-filters .dms-accordion-item__title {
	color: var(--ostz-text);
}

.ostz-filters .dms-accordion-item__chevron {
	color: var(--ostz-text-faint);
}

.ostz-filters .dms-accordion-item__body {
	padding-block-end: var(--ostz-space-2);
}

/* Stock switches. The plugin's pill is a light-theme control — grey track, white knob — which
   reads as a disabled input on a dark surface. */
.ostz-filters .dms-switch-row {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 36px;
	color: var(--ostz-text-dim);
	font-size: var(--ostz-text-sm);
}

.ostz-filters .dms-switch {
	accent-color: var(--ostz-accent);
	background: var(--ostz-bg-sunken);
	border: 1px solid var(--ostz-line-strong);
}

.ostz-filters .dms-switch:checked {
	background: var(--ostz-accent);
	border-color: var(--ostz-accent);
}

.ostz-filters a,
.ostz-filters span,
.ostz-filters label,
.ostz-filters h2,
.ostz-filters h3,
.ostz-filters h4 {
	color: inherit;
}

/*
 * ⚠ Checkbox rhythm. The plugin ships generous padding meant for a full-width sidebar; in a
 * 268px rail it turns six categories into a scroll. Tightened to a 30px row, which is still a
 * comfortable touch target on a phone — going below that trades a real usability property for
 * density, which is not a trade worth making.
 */
.ostz-filters li,
.ostz-filters .dms-term-item {
	margin: 0;
}

.ostz-filters li label,
.ostz-filters .dms-term-item label {
	gap: 8px;
	padding: 4px 4px;
	min-height: 30px;
	line-height: var(--ostz-leading-snug);
}

.ostz-filters input[type='checkbox'],
.ostz-filters input[type='radio'] {
	accent-color: var(--ostz-accent);
	margin: 0;
}

/* ⚠ SECOND INSTANCE of the trap the block above already documents, found 2026-09-06 by
   check-plugin-contract.php: this rule was written for `dms-term-count` / `dms-count`, and the
   plugin has never emitted either name — in the fork or in the market copy. The count pill was
   therefore unstyled the whole time. The real names carry the element's own BEM parent. */
.ostz-filters .dms-term-item__count,
.ostz-filters .dms-attr-item__count {
	color: var(--ostz-text-faint);
	font-size: var(--ostz-text-xs);
	margin-inline-start: auto;
}

/* ---------------------------------------------------------------- the search modal
   Renders into every page's footer, so it is a sitewide surface, not a shop one. Measured on the
   rendered page: a white submit face, a #888 close control and a #3e68ff «show all results»
   button — three of the plugin's own defaults, none of them in this palette. */

/*
 * ⚠ `__panel` AND `__box` ARE CLASSES THE PLUGIN NEVER EMITS. The block below was written against
 * guessed names, matched nothing, and the modal has been a WHITE panel on the dark scheme ever
 * since — invisible to every sweep because the modal was never opened. MEASURED 2026-09-05, opened
 * by a real click: `.dm-search-modal__content` had `background: rgb(255,255,255)` with
 * `data-theme="dark"`, and the close control our own rule had just re-inked measured **1.1:1**.
 *
 * The names are kept for one release in case a plugin update introduces them, but the real element
 * is `__content`, and the plugin builds it from its OWN variables — so the variables are what get
 * pointed at the tokens, the same mechanism the cart drawer already uses. That is more durable
 * than a rule per element: it survives the plugin adding markup we have not seen.
 */
/* ⚠ `.dms-widget` was a fourth entry here and is gone: it is one of the three names the block
   at the top of the rail section records as never emitted, and it survived that clean-up inside a
   selector LIST, where a dead alternative changes nothing visible because its siblings still
   match. A list is exactly where this kind of leftover hides. */
.ostz .dm-search-modal,
.ostz .dm-search-modal__content,
.ostz .dms-sidebar {
	--dms-surface: var(--ostz-bg-raised);
	--dms-surface-alt: var(--ostz-bg-raised-2);
	--dms-surface-muted: var(--ostz-bg-sunken);
	--dms-border: var(--ostz-line);
	--dms-border-light: var(--ostz-line);
	--dms-border-soft: var(--ostz-line);
	--dms-text: var(--ostz-text);
	--dms-text-strong: var(--ostz-text);
	--dms-text-muted: var(--ostz-text-dim);
	--dms-text-soft: var(--ostz-text-dim);
	--dms-primary: var(--ostz-accent);
	--dms-primary-dark: var(--ostz-accent);
	--dms-primary-contrast: var(--ostz-accent-ink);
}

.ostz .dm-search-modal__content,
.ostz .dm-search-modal__panel,
.ostz .dm-search-modal__box {
	background: var(--ostz-bg-raised);
	border-color: var(--ostz-line);
	color: var(--ostz-text);
}

.ostz .dm-search-modal__close {
	color: var(--ostz-text-dim);
	background: transparent;
}

.ostz .dm-search-form__input {
	background: var(--ostz-bg-sunken);
	border-color: var(--ostz-line-strong);
	color: var(--ostz-text);
}

.ostz .dm-search-form__submit {
	background: var(--ostz-accent);
	color: var(--ostz-accent-ink);
	border-color: var(--ostz-accent);
}

.ostz .dm-search-more-btn {
	background: var(--ostz-accent);
	color: var(--ostz-accent-ink);
}

/* ---------------------------------------------------------------- the cart drawer
   The cart-modal plugin is fully settings-driven and emits `--dm-scm-*` custom properties from
   values saved in the database. Saved values are static, so the drawer could not follow the
   scheme — these point the same variables at the tokens instead.

   ⚠ ONLY FOUR NAMES BELONG HERE, and knowing which four is not a matter of taste. This block
   used to declare twelve; the other eight (`panel`, `surface`, `box`, `bg-alt`, `muted`,
   `text-light`, `primary-text`, `danger`) are a generic vocabulary the plugin has never used —
   absent from the fork and from the market copy alike, so those eight lines resolved to nothing.
   The plugin's real vocabulary is PER-CONTROL (`--dm-scm-checkout-bg`, `--dm-scm-pay-btn-bg`,
   `--dm-scm-upsell-bg`, …), it has ~40 of them, and they are owned by its own settings — written
   from this same palette by seeds/seed-cart-modal.php, which is where they must stay so the
   operator keeps control. Adding a name here that the plugin does not read is not harmless: it
   reads as skinning that is already handled and stops anyone looking for the real reason a
   surface is the wrong colour. check-plugin-contract.php now fails on it. */

.dm-scm-drawer,
.dm-scm-drawer-content,
.dm-scm-modal,
.dm-scm-overlay,
body {
	--dm-scm-bg: var(--ostz-bg-raised);
	--dm-scm-text: var(--ostz-text);
	--dm-scm-border: var(--ostz-line);
	--dm-scm-primary: var(--ostz-accent);
}

.dm-scm-drawer-content,
.dm-scm-drawer-header,
.dm-scm-drawer-body,
.dm-scm-drawer-footer,
.dm-scm-modal {
	background: var(--ostz-bg-raised);
	color: var(--ostz-text);
	border-color: var(--ostz-line);
}

.dm-scm-drawer-header,
.dm-scm-drawer-footer {
	border-color: var(--ostz-line);
}

.dm-scm-drawer-content a,
.dm-scm-modal a {
	color: var(--ostz-accent);
}

/*
 * ⚠ THE PANEL WAS THEMED AND ITS CONTENTS WERE NOT, and the difference is the whole finding.
 *
 * MEASURED 2026-09-05, with the drawer OPENED BY A REAL CLICK — the first time it has ever been
 * measured open, because off-canvas the backdrop reading is meaningless and every earlier sweep
 * therefore recorded it as «not re-measured». The panel above correctly takes `bg-raised` and
 * `text`. But the plugin paints its heading, its item titles and its subtotal with a hardcoded
 * `#333`, and its checkout button with hardcoded white ink — literals no variable can reach.
 *
 * On the light scheme that pairing accidentally works, which is why nothing ever looked wrong.
 * On DARK it measured **1.42:1** for «سبد خرید», the item title, «جمع جزء» and the total, and
 * **1.66:1** for «تسویه حساب» — white on our cyan, whose correct ink is near-black. The customer's
 * running total and the button they press to pay were both effectively invisible in the site's
 * own default scheme.
 *
 * ⚠ The lesson for the next plugin: variables reach a plugin only where the plugin USES variables.
 * Where it writes a literal, only a rule on the element itself reaches it — and the only way to
 * find out which is which is to open the thing and measure it.
 */
.dm-scm-drawer-content h3,
.dm-scm-drawer-header h3,
.dm-scm-modal h3,
.dm-scm-modal h4,
.dm-scm-item-title,
.dm-scm-drawer-body .dm-scm-item-title,
/* ⚠ `dm-scm-total-label` / `dm-scm-total-value` were here and neither copy of the plugin has
   ever emitted them; the footer's real names are below. The `strong`/`span` fallbacks at the end
   of this list are what has actually been painting the total all along. */
.dm-scm-drawer-footer .dm-scm-total,
.dm-scm-drawer-footer .dm-scm-total-price,
.dm-scm-cp-totals-row,
.dm-scm-drawer-footer strong,
.dm-scm-drawer-footer span {
	color: var(--ostz-text);
}

.dm-scm-drawer-content .woocommerce-Price-amount,
.dm-scm-modal .woocommerce-Price-amount {
	color: var(--ostz-text);
}

/*
 * The pay button: our accent needs OUR ink on it, not the plugin's white.
 *
 * ⚠ `!important` HERE IS DELIBERATE AND IT IS THE THIRD SANCTIONED USE IN THIS PROJECT (the other
 * two are the nested-table bleed and the `[hidden]` normalize). The plugin writes
 * `.dm-scm-btn-primary { color: #fff !important }`, and an important declaration is beatable only
 * by another one — no amount of specificity reaches it. MEASURED: white on our cyan is **1.66:1**,
 * on the button a customer presses to pay, in the site's own default scheme.
 * ⚠ Do not «tidy» this into a plain declaration; it will silently stop applying.
 */
.dm-scm-drawer-footer .checkout,
.dm-scm-drawer-footer .dm-scm-btn-primary,
.dm-scm-btn-primary,
.dm-scm-modal .dm-scm-btn-primary {
	background: var(--ostz-accent) !important;
	border-color: transparent;
	color: var(--ostz-accent-ink) !important;
}

/* Measured 19×18 — the control that removes a line from the cart, under the 24px tap floor. */
.dm-scm-remove-item,
.dm-scm-drawer-body .dm-scm-remove-item {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 26px;
	block-size: 26px;
}

/* The search modal's close control measured 2.17:1 against 3 — an icon-only escape route. */
.dm-search-modal__close,
.dm-search-modal .dm-search-modal__close {
	color: var(--ostz-text);
}

/* ---------------------------------------------------------------- the login controls
   ⚠ The OTP button is the single most important control in the purchase path, and it was wearing
   the plugin's own colour rather than the site's. Both entry points get the same treatment: the
   modal that opens anywhere on the site, and the standalone forced-login page, which never loads
   the theme stylesheet and so is handed the same variables through the plugin's own hook. */

.dml-btn-primary,
.dml-btn.dml-btn-primary,
button.dml-btn-primary {
	background: var(--ostz-accent);
	border-color: transparent;
	color: var(--ostz-accent-ink);
	font-family: inherit;
	font-weight: var(--ostz-weight-bold);
}

.dml-btn-primary:hover {
	filter: brightness(1.08);
	color: var(--ostz-accent-ink);
}

.dml-btn:not(.dml-btn-primary) {
	background: var(--ostz-bg-raised-2);
	border-color: var(--ostz-line-strong);
	color: var(--ostz-text);
	font-family: inherit;
}

.dml-btn:not(.dml-btn-primary):hover {
	border-color: var(--ostz-accent);
	color: var(--ostz-accent);
}

/* ---------------------------------------------------------------- product engagement
 *
 * The waitlist control and its dialog. ⚠ On a «به‌زودی» product there is no add-to-cart, so this
 * is the ONLY action on the page — and on a store where 20 of 26 products are priceless today,
 * it is the only conversion path there is. It rendered as a bare line of text: its markup carried
 * `btn btn-primary`, which are Bootstrap names, and this site ships no Bootstrap, so the control
 * matched zero rules in zero stylesheets. The fork now emits a real <button>; this gives it a look.
 */

.dm-waitlist-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-height: 40px;
	padding: 0 16px;
	border: 1px solid var(--ostz-accent);
	border-radius: var(--ostz-radius-sm);
	background: color-mix(in srgb, var(--ostz-accent) 12%, transparent);
	color: var(--ostz-accent);
	font-family: inherit;
	font-size: var(--ostz-text-sm);
	font-weight: var(--ostz-weight-bold);
	line-height: var(--ostz-leading-tight);
	cursor: pointer;
	transition: background .18s ease, color .18s ease, border-color .18s ease;
}

.dm-waitlist-btn:hover {
	background: var(--ostz-accent);
	color: var(--ostz-accent-ink);
}

.dm-waitlist-btn:focus-visible {
	outline: 2px solid var(--ostz-accent);
	outline-offset: 2px;
}

/* Already on the list: an outline rather than a fill, so the two states differ by more than a word
   and a returning visitor can see at a glance which products they are waiting on. */
.dm-waitlist-btn.active {
	border-color: var(--ostz-line-strong);
	background: transparent;
	color: var(--ostz-text-dim);
}

.dm-waitlist-btn .dm-icon {
	display: inline-flex;
	line-height: 0;
}

/* On a card the control sits under a compact button and matches its size. */
.ostz-card .dm-waitlist-btn {
	width: 100%;
	min-height: 34px;
	font-size: var(--ostz-text-xs);
}

/* The dialog it opens. Its submit was #007cba — WordPress's admin blue, on the only conversion
   action of a pre-launch store, inside a panel this theme had already skinned dark. */
.dm-modal-content {
	background: var(--ostz-bg-raised);
	color: var(--ostz-text);
	border: 1px solid var(--ostz-line-strong);
	border-radius: var(--ostz-radius);
}

.dm-modal-body input[type='tel'],
.dm-modal-body input[type='text'],
.dm-modal-body input[type='email'] {
	background: var(--ostz-bg-sunken);
	border: 1px solid var(--ostz-line);
	color: var(--ostz-text);
	font-family: inherit;
}

.dm-modal-body input::placeholder {
	color: var(--ostz-text-faint);
}

.dm-submit-btn,
.button.dm-submit-btn {
	background: var(--ostz-accent);
	border-color: transparent;
	color: var(--ostz-accent-ink);
	font-family: inherit;
	font-weight: var(--ostz-weight-bold);
}

.dm-submit-btn:hover,
.button.dm-submit-btn:hover {
	background: var(--ostz-accent);
	color: var(--ostz-accent-ink);
	filter: brightness(1.08);
}

/* ---------------------------------------------------------------- plugin tap targets
 *
 * Three controls from the forked plugins measured under the 24x24 floor: the search modal's close
 * (14x24), the cart drawer's close (12x24) and the filter rail's stock switch (36x20). Each is the
 * only way out of, or into, the surface it belongs to. Sized here rather than in the forks because
 * it is a house rule about our UI, not a defect in their logic — and a rule stated once in the skin
 * cannot drift out of step with the plugin's own updates.
 */

.dm-search-modal__close,
.dm-scm-drawer-close,
.dm-scm-close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 32px;
	min-height: 32px;
	border-radius: 8px;
	/* The plugins ship a mid-grey close glyph that measures under the floor on both of these dark
	   panels. Same token as every other secondary control on the site. */
	color: var(--ostz-text-dim);
}

/* The drawer's empty state and its badge, both plugin defaults chosen for a light theme. */
.dm-scm-empty-cart {
	color: var(--ostz-text-dim);
}

/*
 * ⚠ This used to declare `background`/`color` directly and it NEVER APPLIED. The plugin declares
 * the same bare `.dm-scm-count-badge` selector — 0-1-0 against our 0-1-0 — and its stylesheet is
 * enqueued after ours, so load order decided it and the plugin won on every page of the site.
 * MEASURED before the fix: white on #EF3E63 at 3.79:1, not our accent, on all 44 surfaces.
 *
 * The plugin now exposes the badge as custom properties (dm-smart-cart-modal 2.30.6), so we SET
 * THE PROPERTIES rather than re-declaring the paint. A custom property is inherited, not matched,
 * so specificity and load order stop deciding anything.
 */
.dm-scm-count-badge {
	--dm-scm-count-bg: var(--ostz-accent);
	--dm-scm-count-ink: var(--ostz-accent-ink);
	font-weight: var(--ostz-weight-bold);
}

.dm-search-modal__close:hover,
.dm-scm-drawer-close:hover,
.dm-scm-close:hover {
	background: var(--ostz-bg-raised-2);
	color: var(--ostz-text);
}

.ostz-filters .dms-switch,
.ostz-filters input.dms-switch {
	min-width: 36px;
	min-height: 24px;
}

/* The row is the real target — a 24px switch is reachable, but the label beside it is what a thumb
   actually lands on. */
.ostz-filters .dms-switch-row {
	min-height: 44px;
	cursor: pointer;
}
