/* JustLoofah COD order form — RTL, Arabic-first. */
@import url("https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700&display=swap");

/* Type-scale tokens, in px — deliberately independent of the host theme's
   <html> font-size. The installed theme sets html{font-size:62.5%} (root =
   10px), which silently rendered every one of this file's old rem-based
   font-sizes at ~62% of its authored size (labels at 9px, the tax note at
   7.8px). em with a single base per root was ruled out too: .cod-form nests
   inside .cod-form (blocks/cod-cart.liquid -> snippets/cod-cart-body.liquid,
   blocks/cod-form.liquid -> snippets/cod-form-body.liquid), so an em scale
   would compound to base^2 for the nested copy and change again when
   cod-core.js relocates the form into the modal panel. Declared on each of
   the form's independent root trees; every consumer below still carries an
   inline `var(--x, <px>)` fallback because cod-core.js's no-donor launcher
   branch renders .cod-form__submit outside any of these roots. */
.cod-form,
.cod-offer {
  --cod-fs-2xs: 13px;
  --cod-fs-xs: 14px;
  --cod-fs-sm: 15px;
  --cod-fs-md: 16px;
  --cod-fs-lg: 17px;
  --cod-fs-xl: 19px;
  --cod-fs-2xl: 22px;
  --cod-fs-3xl: 28px;
  direction: rtl;
  text-align: right;
  font-family: "Cairo", "IBM Plex Sans Arabic", "Tajawal", system-ui, -apple-system, sans-serif;
  max-width: 560px;
  margin: 24px auto;
  color: #2b2722;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.6;
  letter-spacing: normal;
  word-spacing: normal;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* .cod-offer is a standalone offer block that intentionally reuses the
   form's tier/add-on components (see below) so moving selection out of the
   form does not change the visual language or RTL spacing — it was
   byte-identical to .cod-form above, now collapsed into one rule. */
.cod-offer__notice {
  padding: 12px 14px;
  border: 1px solid #e3a11c;
  border-radius: 12px;
  background: #fff7e6;
  color: #6b4d0b;
  font-size: var(--cod-fs-sm, 15px);
  line-height: 1.6;
}

.cod-form__loading {
  padding: 24px;
  text-align: center;
  color: #857a6a;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.6;
}

.cod-form__title {
  /* This is an <h3>, and themes routinely style headings by element —
     Dawn's base.css has `h1,h2,h3,h4,h5 { font-family: var(--font-heading-family) }`.
     Our Cairo stack is only *inherited* from the .cod-form root, and an
     inherited value always loses to a rule that matches the element directly,
     no matter how low its specificity. Without this the section headings
     silently render in the theme's heading font while the labels and inputs
     beside them render Cairo. */
  font-family: inherit;
  font-size: var(--cod-fs-xl, 19px);
  line-height: 1.35;
  font-weight: 700;
  margin: 22px 0 12px;
}

/* Tiers */
.cod-form__tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.cod-tier {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 14px 10px;
  border: 2px solid #e7ded0;
  border-radius: 14px;
  background: #fff;
  cursor: pointer;
  font-family: inherit;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s;
}
.cod-tier:active {
  transform: scale(0.99);
}
.cod-tier.is-selected {
  border-color: #e3a11c;
  box-shadow: 0 0 0 3px rgba(227, 161, 28, 0.18);
}
.cod-tier:focus-visible {
  outline: 3px solid rgba(227, 161, 28, 0.5);
  outline-offset: 2px;
}
/* .cod-tier is a <label> now, not a <button> (a <select> can't live inside
   a <button> — see cod-offer-controls.liquid), paired with a sibling
   <input type="radio"> that carries the actual checked state. The radio is
   visually hidden but still focusable/clickable (position:absolute removes
   it from .cod-form__tiers' grid/flex flow without display:none, which
   would also remove it from the Tab order) — :focus-visible on it repaints
   the exact outline .cod-tier itself used to show as a focusable <button>. */
.cod-tier-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  opacity: 0;
  pointer-events: none;
}
.cod-tier-radio:focus-visible + .cod-tier {
  outline: 3px solid rgba(227, 161, 28, 0.5);
  outline-offset: 2px;
}
.cod-tier__label {
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.35;
  font-weight: 700;
}
.cod-tier__price {
  font-size: var(--cod-fs-xl, 19px);
  line-height: 1.25;
  font-weight: 700;
  color: #2b2722;
  font-variant-numeric: tabular-nums;
}
.cod-tier__compare {
  font-size: var(--cod-fs-xs, 14px);
  line-height: 1.3;
  color: #a99e8c;
  text-decoration: line-through;
}
.cod-tier__desc {
  font-size: var(--cod-fs-xs, 14px);
  line-height: 1.45;
  color: #857a6a;
  text-align: center;
}

/* Phase 3 tier display fields — genuinely NEW classes, so none of this
   touches .cod-tier/.cod-tier__label/.cod-tier__price/.cod-tier__compare/
   .cod-tier__desc above. Each element only exists in the DOM when its
   Liquid field is present (cod-offer-controls.liquid), so a tier carrying
   none of them stays byte-identical to before Phase 3 in either layout. */
.cod-tier__badge {
  font-family: inherit;
  font-size: var(--cod-fs-2xs, 13px);
  line-height: 1.3;
  font-weight: 700;
  color: #6b4d0b;
  background: #fff2cf;
  border-radius: 999px;
  padding: 2px 8px;
  align-self: flex-start;
}
.cod-tier__popular {
  font-family: inherit;
  font-size: var(--cod-fs-2xs, 13px);
  line-height: 1.3;
  font-weight: 700;
  color: #fff;
  background: #e3a11c;
  border-radius: 999px;
  padding: 2px 8px;
  align-self: flex-start;
}
.cod-tier__per-unit {
  font-size: var(--cod-fs-2xs, 13px);
  line-height: 1.3;
  color: #857a6a;
  font-variant-numeric: tabular-nums;
}
.cod-tier__savings {
  font-size: var(--cod-fs-2xs, 13px);
  line-height: 1.3;
  font-weight: 700;
  color: #3fa34d;
}

/* ---------------------------------------------------------------------
   Bars layout — wrapper modifier ONLY (form_config.tier_layout: "bars",
   default "cards"). Every selector below is scoped under .cod-tiers--bars
   so none of it is a bare, unscoped rule for .cod-tier / .cod-tier__label /
   .cod-tier__price / .cod-tier__compare / .cod-tier__desc / .cod-form__tiers
   — those stay exactly as they render today under the default "cards"
   layout, which is what's live on nahleh's published theme right now.
   RTL-safe throughout: logical inset-inline properties, never `right:`;
   no rem/em anywhere (CLAUDE.md's "Storefront CSS must never use rem" —
   font-sizes here reuse the existing var(--cod-fs-*, <px>) tokens, no new
   ones declared). ----------------------------------------------------- */
/* Compound selector (0-2-0), NOT a bare `.cod-tiers--bars` (0-1-0). Both
   classes sit on the same element, and `.cod-form__tiers` above sets
   `display: grid` as a single-class selector (0-1-0) too — so two
   single-class rules would tie at 0-1-0 and resolve by source order alone.
   Writing the compound form here (0-2-0) makes the bars layout win
   independently of where this rule sits in the file. `grid-template-columns`
   is reset as belt-and-braces, in case a future rule flips `display` back. */
.cod-form__tiers.cod-tiers--bars {
  display: flex;
  flex-direction: column;
  grid-template-columns: none;
  gap: 8px;
}
.cod-tiers--bars .cod-tier {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: 10px;
  width: 100%;
  text-align: start;
  padding: 12px 14px;
  border-radius: 12px;
  transition: border-color 0.15s, background-color 0.15s, box-shadow 0.15s;
}
/* Selection affordance. The real input is visually hidden (.cod-tier-radio at
   113 is 1px/opacity 0), so before this there was no dot, ring or check
   anywhere and nothing signalled that the bars were choices at all. This
   pseudo-element is a decorative radio dot occupying a new inline-start grid
   column; the input keeps every bit of the semantics. Grid columns follow
   `direction`, so it lands on the correct side under RTL with no logical
   offset needed. */
.cod-tiers--bars .cod-tier::before {
  content: "";
  width: 20px;
  height: 20px;
  box-sizing: border-box;
  border-radius: 999px;
  border: 2px solid #d9cfbe;
  background: #fff;
  align-self: center;
}
/* Recommended tier — deliberately QUIETER than the selected state, and
   deliberately placed BEFORE it. This selector and
   `.cod-tiers--bars .cod-tier.is-selected` below are both specificity 0-3-0,
   so they tie and resolve by source order alone: recommended first means
   selected always wins on a tier that is both. Reordering these two rules
   silently makes the selected state invisible on the popular tier. */
.cod-tiers--bars .cod-tier:has(.cod-tier__popular) {
  border-color: #f0d9a3;
  background: #fffdf6;
}
/* Selected state. Hooked on BOTH the `:checked` sibling (CSS-native, cannot
   drift) and the `.is-selected` class the JS writes, so it holds whichever
   sets state first. Measured in the browser: radio.checked and .is-selected
   are always in sync, so the two hooks never disagree. */
.cod-tiers--bars .cod-tier-radio:checked + .cod-tier,
.cod-tiers--bars .cod-tier.is-selected {
  border-color: #e3a11c;
  background: #fff8ec;
  box-shadow: 0 0 0 3px rgba(227, 161, 28, 0.22), 0 1px 2px rgba(43, 39, 34, 0.06);
}
.cod-tiers--bars .cod-tier-radio:checked + .cod-tier::before,
.cod-tiers--bars .cod-tier.is-selected::before {
  border-color: #e3a11c;
  background: radial-gradient(circle at center, #e3a11c 0 42%, #fff 47% 100%);
}
.cod-tiers--bars .cod-tier__info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-width: 0;
  text-align: start;
}
/* Price hierarchy. This was a 4-row column (compare / price / per-unit /
   savings) which made every discounted bar 35px taller than the plain one and
   put the strikethrough ABOVE the real price. A 2x2 grid with explicit
   per-class placement gives every tier a predictable 2-line block and is
   robust to any of the three optional children being absent — nth-child
   placement would not be, since compare, per-unit and savings each render
   only when their field is set. */
.cod-tiers--bars .cod-tier__pricing {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: end;
  align-items: baseline;
  column-gap: 6px;
  row-gap: 1px;
  flex-shrink: 0;
  text-align: end;
}
.cod-tiers--bars .cod-tier__price {
  grid-column: 1;
  grid-row: 1;
}
.cod-tiers--bars .cod-tier__compare {
  grid-column: 2;
  grid-row: 1;
}
.cod-tiers--bars .cod-tier__per-unit {
  grid-column: 1;
  grid-row: 2;
}
/* The savings string is authored "-25%" (U+2D U+32 U+35 U+25) but rendered
   "25%-" — under `direction: rtl` the leading ASCII hyphen is a bidi-neutral
   character and gets reordered to the visual end. Isolating the run in an LTR
   embedding renders it as authored. The cards layout has the identical defect
   and is deliberately NOT fixed here, because cards is live on production. */
.cod-tiers--bars .cod-tier__savings {
  grid-column: 2;
  grid-row: 2;
  direction: ltr;
  unicode-bidi: isolate;
}
/* Badge de-emphasis. `badge_text` has no cross-tier validation, so a merchant
   can set "most popular" on two tiers at once and split the shopper's
   attention. Demoting the badge to a muted outline pill keeps the solid
   `.cod-tier__popular` chip (single-enforced, client and server) as the one
   loud recommendation even when the config carries duplicates. */
.cod-tiers--bars .cod-tier__badge {
  background: transparent;
  border: 1px solid #e7ded0;
  color: #857a6a;
  font-weight: 600;
}
.cod-tiers--bars .cod-tier__popular {
  box-shadow: 0 1px 2px rgba(43, 39, 34, 0.12);
}
.cod-tiers--bars .cod-tier__desc {
  text-align: start;
}

/* Per-bar per-option variant pickers (cod-offer-controls.liquid's
   cod_show_variant_picks / cod-core.js's buildBarVariantPicks +
   bindBarVariantPicks) — selects live INSIDE every bar, under an
   option-name header, one row per pack unit numbered #1/#2/… (the number
   omitted entirely for a quantity-1 tier). Scoped under .cod-tiers--bars
   like every other rule in this section: cards keeps its separate
   below-the-list picker (.cod-form__variants below) untouched. Spans the
   full row width under .cod-tiers--bars .cod-tier's 2-column grid. No
   rem font-sizes; .cod-tier__variant-select reuses .cod-field__input for
   its font/color/border (both already carry the --cod-fs-* px tokens). */
.cod-tiers--bars .cod-tier__variants {
  grid-column: 1 / -1;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  gap: 6px 10px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid #e7ded0;
}
.cod-tiers--bars .cod-tier__variant-names {
  display: flex;
  flex: 1 0 100%;
  flex-wrap: wrap;
  column-gap: 12px;
  row-gap: 2px;
  font-size: var(--cod-fs-xs, 14px);
  font-weight: 600;
  color: #6b6355;
}
.cod-tiers--bars .cod-tier__variant-unit {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 140px;
}
/* Same bidi problem as the savings chip: the unit number is two spans,
   <span>#</span><span>N</span>, and RTL reorders them to render "1 #". */
.cod-tiers--bars .cod-tier__variant-number {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  font-size: var(--cod-fs-xs, 14px);
  font-weight: 700;
  color: #857a6a;
  font-variant-numeric: tabular-nums;
  direction: ltr;
  unicode-bidi: isolate;
}
.cod-tiers--bars .cod-tier__variant-selects {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.cod-tiers--bars .cod-tier__variant-select {
  flex: 1;
  min-width: 96px;
  min-height: 34px;
  padding: 4px 8px;
  font-size: var(--cod-fs-xs, 14px);
  cursor: pointer;
}
/* Collapse the pickers on every bar except the active one. They used to render
   expanded inside all bars simultaneously, so an unselected bar paid 75px of
   picker height it could not act on. Verified in the browser that the select
   values survive hide/reveal, so bindBarVariantPicks' seeding and its
   selectionsByTier map are unaffected. Both hooks for the same reason as the
   selected state above. */
.cod-tiers--bars .cod-tier:not(.is-selected) .cod-tier__variants {
  display: none;
}
.cod-tiers--bars .cod-tier-radio:not(:checked) + .cod-tier .cod-tier__variants {
  display: none;
}

/* Upsells */
.cod-form__upsells {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cod-upsell {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid #e7ded0;
  border-radius: 12px;
  cursor: pointer;
}
.cod-upsell__cb {
  width: 18px;
  height: 18px;
  accent-color: #e3a11c;
}
.cod-upsell.is-disabled,
.cod-upsell__cb:disabled {
  opacity: 0.58;
  cursor: not-allowed;
}
.cod-upsell__img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 8px;
}
.cod-upsell__title {
  flex: 1;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.45;
}
.cod-upsell__price {
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.45;
  font-weight: 600;
  color: #6b6355;
}
/* Phase 3 — additive-only, same convention as .cod-tier__compare: only in
   the DOM when the upsell carries compare_at_price. */
.cod-upsell__compare {
  font-size: var(--cod-fs-xs, 14px);
  line-height: 1.3;
  color: #a99e8c;
  text-decoration: line-through;
  font-variant-numeric: tabular-nums;
}

/* Mix-and-match per-unit variant pickers (cod-core.js: renderVariantPicks).
   Rendered ONLY when a tier's quantity is 2+ AND the product has 2+
   variants — a single-variant product gets none of this markup at all.
   Reuses .cod-field__input / .cod-field__label verbatim (both already carry
   the --cod-fs-* px tokens declared on .cod-form/.cod-offer above) so this
   adds no new font-size, per CLAUDE.md's "Storefront CSS must never use
   rem" gate. */
.cod-form__variants {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 12px;
}
.cod-variant-pick {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.cod-variant-pick__select {
  cursor: pointer;
}

/* Form fields */
.cod-form__fields {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.cod-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.cod-field__label {
  font-size: var(--cod-fs-sm, 15px);
  line-height: 1.5;
  font-weight: 600;
  color: #55504a;
}
.cod-field__input {
  width: 100%;
  box-sizing: border-box;
  padding: 13px 14px;
  min-height: 48px;
  border: 1px solid #d9cfbe;
  border-radius: 10px;
  font-family: inherit;
  /* Hard floor: must never resolve below 16px at any breakpoint, or iOS
     zooms the viewport on focus. --cod-fs-md is 16px desktop / 17px
     mobile — always above the floor. */
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.5;
  background: #fff;
  color: inherit;
}
.cod-field__input:focus {
  outline: none;
  border-color: #e3a11c;
  box-shadow: 0 0 0 3px rgba(227, 161, 28, 0.15);
}

/* Composite phone field: country-code select + numeric local-number input */
.cod-field__phone {
  display: flex;
  flex-direction: row;
  gap: 8px;
}
.cod-field__cc {
  /* Always rendered with the .cod-field__input class alongside this one
     (see cod-core.js and the *-body.liquid templates), so it already gets
     that rule's font-size/min-height. Width stays in em (not px) so it
     keeps auto-tracking whatever that font-size resolves to. */
  flex: 0 0 auto;
  width: 6.5em;
  padding-inline: 8px;
}
.cod-field__phone-input {
  flex: 1;
}

/* Quantity selector (simple/non-bundle mode). No rule previously existed
   for either class — the input inherited only .cod-field__input and
   rendered as a full-width text field. */
.cod-form__qty,
.cod-field__qty {
  width: 96px;
  min-height: 48px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Summary */
.cod-form__summary {
  border: 1px solid #e7ded0;
  border-radius: 12px;
  padding: 12px 14px;
  background: #fbf8f3;
}
.cod-summary__row {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
}
.cod-summary__row.is-total {
  border-top: 1px dashed #d9cfbe;
  margin-top: 6px;
  padding-top: 10px;
  font-weight: 700;
  font-size: var(--cod-fs-xl, 19px);
  line-height: 1.4;
}

/* Whole-cart summary line items (cart form, drawer, product whole-cart).
   RTL flex row: media (image + qty badge) sits at the right, title grows,
   price then remove-✕ trail to the left — matching the reference design. */
.cod-cartline {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid #ece3d4;
}
.cod-cartline:first-child {
  padding-top: 2px;
}
.cod-cartline__media {
  position: relative;
  flex: 0 0 auto;
}
.cod-cartline__img {
  display: block;
  width: 52px;
  height: 52px;
  object-fit: cover;
  border-radius: 10px;
}
/* Qty badge is a fixed circle pinned to the image corner: glyph size, box
   size/line-height, and offset move together as one unit, or a 2-digit
   quantity clips or drifts off the corner. Offset = -(box/2 - 3), i.e. the
   badge sits centred on the corner with a consistent 3px overlap. Verify
   at qty 1, 12, and 100. */
.cod-cartline__qty {
  position: absolute;
  top: -8px;
  inset-inline-start: -8px;
  min-width: 22px;
  height: 22px;
  box-sizing: border-box;
  padding: 0 5px;
  border-radius: 999px;
  background: #2b2722;
  color: #fff;
  font-size: var(--cod-fs-2xs, 13px);
  font-weight: 700;
  line-height: 22px;
  text-align: center;
}
.cod-cartline__info {
  flex: 1;
  min-width: 0;
}
.cod-cartline__title {
  font-weight: 600;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.4;
}
.cod-cartline__price {
  flex: 0 0 auto;
  font-weight: 700;
  white-space: nowrap;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
}
.cod-cartline__remove {
  flex: 0 0 auto;
  /* Tap target 26px -> 32px desktop / 36px mobile (merchant-requested).
     Full 44px would dominate a 76px cart row; this plus the row's own hit
     area is the accepted compromise. */
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: #a99e8c;
  font-family: inherit;
  font-size: var(--cod-fs-sm, 15px);
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.cod-cartline__remove:hover {
  background: #fdeceb;
  color: #b3261e;
}
.cod-summary__totals {
  margin-top: 10px;
}
.cod-summary__tax {
  margin-top: 4px;
  font-size: var(--cod-fs-xs, 14px);
  line-height: 1.5;
  color: #6b6355;
  text-align: start;
}

/* Submit */
.cod-form__submit {
  width: 100%;
  margin-top: 16px;
  padding: 15px;
  border: none;
  border-radius: 12px;
  background: #e3a11c;
  color: #fff;
  font-family: inherit;
  font-size: var(--cod-fs-xl, 19px);
  line-height: 1.3;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
  /* Anchors the .is-busy spinner below (position: absolute is relative to
     this). Inert otherwise — .cod-form__submit was already the button's own
     stacking/layout context in every use, so this changes nothing visible
     when not busy. */
  position: relative;
}
.cod-form__submit:hover {
  background: #cf9013;
}
.cod-form__submit:disabled {
  opacity: 0.65;
  cursor: default;
}
/* Submit-in-flight spinner, toggled in cod-core.js (setSubmitBusy) alongside
   the existing disabled + textContent handling — never a replacement for
   either. The CTA text stays visible (it carries the two-stage progress
   copy on the whole-cart flow); the spinner only augments it, so
   padding-inline-end makes room rather than overlapping. inset-inline-end
   (not left/right) so this sits at the correct edge under this form's RTL
   direction without a direction-specific override. */
.cod-form__submit.is-busy {
  padding-inline-end: 40px;
}
.cod-form__submit.is-busy::after {
  content: "";
  position: absolute;
  top: 50%;
  inset-inline-end: 15px;
  width: 18px;
  height: 18px;
  margin-top: -9px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  animation: cod-submit-spin 0.7s linear infinite;
}
@keyframes cod-submit-spin {
  to {
    transform: rotate(360deg);
  }
}
/* sr-only aria-live="polite" status region (ensureStatusRegion in
   cod-core.js) — mirrors the button's busy-stage text for screen readers,
   which don't reliably announce a <button>'s own textContent changes.
   Standard visually-hidden-but-announced pattern; not display:none, which
   would pull it out of the accessibility tree too. */
.cod-form__status {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.cod-form__error {
  margin-top: 12px;
  padding: 11px 14px;
  border-radius: 10px;
  background: #fdeceb;
  color: #b3261e;
  font-size: var(--cod-fs-sm, 15px);
  line-height: 1.55;
}

/* Result */
.cod-form__result {
  text-align: center;
  padding: 28px 16px;
  border: 1px solid #e7ded0;
  border-radius: 16px;
  background: #f6fbf4;
}
/* Was a line-height-as-box-height hack (line-height:54px on a 54px circle),
   which couples glyph baseline to box height and breaks the moment either
   changes. Decoupled: flex-centering sizes the box, line-height:1 keeps the
   glyph from adding its own leading on top of that. */
.cod-result__check {
  width: 60px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 12px;
  border-radius: 50%;
  background: #3fa34d;
  color: #fff;
  font-size: var(--cod-fs-3xl, 28px);
  line-height: 1;
  font-weight: 700;
}
.cod-result__title {
  font-size: var(--cod-fs-2xl, 22px);
  line-height: 1.35;
  font-weight: 700;
}
.cod-result__order {
  margin-top: 6px;
  color: #6b6355;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.5;
}
.cod-result__hint {
  margin-top: 14px;
  font-size: var(--cod-fs-sm, 15px);
  line-height: 1.6;
  color: #6b6355;
}
.cod-result__again {
  margin-top: 16px;
}

/* Popup launcher (display_mode: popup) */
.cod-form__launcher {
  margin-top: 0;
}

/* Embed auto-mount launcher (P6) — same look as .cod-form__submit; inserted
   directly into theme markup (not inside a .cod-form root) so it can't rely
   on cascade from a COD form/block wrapper. RTL-safe (no directional
   properties beyond what .cod-form__submit already sets via inheritance).
   Deliberately has NO font-size: cod-core.js clones the theme's own donor
   button class here so the launcher matches the surrounding theme. */
.cod-embed-launcher {
  display: block;
  box-sizing: border-box;
  text-align: center;
}

/* Modal / drawer overlay (popup display mode) — RTL-friendly */
.cod-modal {
  --cod-fs-2xs: 13px;
  --cod-fs-xs: 14px;
  --cod-fs-sm: 15px;
  --cod-fs-md: 16px;
  --cod-fs-lg: 17px;
  --cod-fs-xl: 19px;
  --cod-fs-2xl: 22px;
  --cod-fs-3xl: 28px;
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  direction: rtl;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.6;
  letter-spacing: normal;
  word-spacing: normal;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
.cod-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(43, 39, 34, 0.55);
}
.cod-modal__panel {
  position: relative;
  width: 100%;
  max-width: 620px;
  /* min() of vh and dvh so the iOS Safari URL bar can't eat the panel
     bottom when it collapses/expands mid-scroll. */
  max-height: min(88vh, 88dvh);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: #fbf8f3;
  border: 1px solid #e7ded0;
  border-radius: 16px;
  padding: 18px 20px 26px;
  box-shadow: 0 18px 48px rgba(43, 39, 34, 0.32);
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.6;
}
.cod-modal__close {
  position: absolute;
  /* Tap target 34px -> 40px desktop / 44px mobile (merchant-requested);
     offset grown to match so it stops crowding the first title. */
  top: 14px;
  inset-inline-end: 14px;
  width: 40px;
  height: 40px;
  border: 1px solid #e7ded0;
  border-radius: 50%;
  background: #fff;
  color: #6b6355;
  font-size: var(--cod-fs-sm, 15px);
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}
.cod-modal__close:hover {
  border-color: #e3a11c;
  color: #2b2722;
}
.cod-modal__content.cod-form {
  margin: 10px auto 0;
}
body.cod-modal-open {
  overflow: hidden;
}

/* ---------------------------------------------------------------------
   Sticky Add to Cart Bar — RTL, Arabic-first. Additive; SSR by
   blocks/cod-embed.liquid only when block.settings.sticky_enable is on.
   All colors come from --cod-sticky-* custom properties set inline by
   Liquid so merchant color-picker settings apply without a build step.
   z-index sits BELOW the COD modal (2147483000) so the modal always
   layers above the bar.

   That z-index (2147482900) also beats any theme cart-drawer z-index,
   which on mobile means the bar renders ON TOP of an open cart drawer and
   covers the drawer's checkout button. The z-index ordering above is not
   the whole story: html.cod-drawer-open (toggled by syncDrawerGate() in
   cod-core.js) and body.cod-modal-open (toggled by the COD modal) both
   force-hide the bar entirely rather than re-layer it — see the rule
   right after .cod-sticky--devices-desktop below. --------------------- */
.cod-sticky {
  --cod-sticky-radius: 16px;
  --cod-fs-2xs: 13px;
  --cod-fs-xs: 14px;
  --cod-fs-sm: 15px;
  --cod-fs-md: 16px;
  --cod-fs-lg: 17px;
  --cod-fs-xl: 19px;
  --cod-fs-2xl: 22px;
  --cod-fs-3xl: 28px;
  position: fixed;
  inset-inline: 0;
  z-index: 2147482900;
  display: flex;
  align-items: center;
  gap: 12px;
  direction: rtl;
  font-family: "Cairo", "IBM Plex Sans Arabic", "Tajawal", system-ui, -apple-system, sans-serif;
  background: var(--cod-sticky-bg, #ffffff);
  box-sizing: border-box;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.6;
  letter-spacing: normal;
  word-spacing: normal;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

.cod-sticky--bottom {
  bottom: 0;
}
.cod-sticky--top {
  top: 0;
}

.cod-sticky--shadow-none {
  box-shadow: none;
}
.cod-sticky--shadow-soft {
  box-shadow: 0 -4px 16px rgba(43, 39, 34, 0.12);
}
.cod-sticky--shadow-strong {
  box-shadow: 0 -8px 28px rgba(43, 39, 34, 0.24);
}
.cod-sticky--top.cod-sticky--shadow-soft {
  box-shadow: 0 4px 16px rgba(43, 39, 34, 0.12);
}
.cod-sticky--top.cod-sticky--shadow-strong {
  box-shadow: 0 8px 28px rgba(43, 39, 34, 0.24);
}

/* Device-visibility utility classes */
.cod-sticky--devices-mobile {
  display: none;
}
.cod-sticky--devices-desktop {
  display: none;
}

/* Force-hide the bar rather than re-layer it under a drawer/modal.
   html.cod-drawer-open is set by syncDrawerGate() in cod-core.js whenever
   an open theme cart drawer reaches the viewport edge the bar is pinned to.
   body.cod-modal-open is already set by the COD modal (see the rule at
   ~line 530 above) — needed here too because the modal's translucent
   backdrop (rgba(43,39,34,.55)) does not cover the bar's card, so the bar
   glows through at the bottom; and because closeThemeCartDrawer() closes
   the drawer before the modal opens, which would otherwise clear the
   drawer gate and let the bar pop straight back through the backdrop.
   !important is defensive only: html.cod-drawer-open .cod-sticky (0,2,1)
   already outspecifies .cod-sticky--devices-both { display: flex } (0,1,0)
   inside the device media queries below. */
html.cod-drawer-open .cod-sticky,
body.cod-modal-open .cod-sticky {
  display: none !important;
}

.cod-sticky__image {
  flex-shrink: 0;
  width: 56px;
  height: 56px;
  border-radius: calc(var(--cod-sticky-radius) / 2);
  overflow: hidden;
  background: #f4efe6;
}
.cod-sticky__image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cod-sticky__info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cod-sticky__title {
  color: var(--cod-sticky-title-color, #2b2722);
  /* Sticky bar is position:fixed and permanently eats viewport height, so
     its type grows conservatively (+1-2px over the old rem-at-16px-root
     estimate) with a tight line-height — scaling it like the rest of the
     form would push more page content off-screen on mobile. */
  font-size: var(--cod-fs-xs, 14px);
  line-height: 1.25;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cod-sticky__stars {
  display: flex;
  align-items: center;
  gap: 2px;
  color: var(--cod-sticky-star-color, #e3a11c);
  /* 2xs is the one token that does NOT grow on mobile (13px at both
     breakpoints) — the right fit for a fixed-height bar row. */
  font-size: var(--cod-fs-2xs, 13px);
  line-height: 1.2;
}
.cod-sticky__star {
  color: var(--cod-sticky-star-color, #e3a11c);
}
.cod-sticky__star-score {
  font-weight: 700;
  color: var(--cod-sticky-title-color, #2b2722);
  margin-inline-start: 4px;
}
.cod-sticky__review-count {
  color: #857a6a;
}

.cod-sticky__prices {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.cod-sticky__price {
  color: var(--cod-sticky-price-color, #2b2722);
  font-weight: 700;
  font-size: var(--cod-fs-md, 16px);
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
}
.cod-sticky__compare {
  color: var(--cod-sticky-compare-color, #a39a8b);
  font-size: var(--cod-fs-xs, 14px);
  line-height: 1.25;
  text-decoration: line-through;
}

.cod-sticky__cta {
  flex-shrink: 0;
  border: none;
  cursor: pointer;
  background: var(--cod-sticky-btn-bg, #e3a11c);
  color: var(--cod-sticky-btn-text, #ffffff);
  font-family: inherit;
  font-weight: 700;
  transition: background-color 0.15s ease;
}
.cod-sticky__cta:hover,
.cod-sticky__cta:active {
  background: var(--cod-sticky-btn-hover, #c98a12);
}

/* Mobile card — image on the right, title/stars/prices stacked and
   right-aligned to its left, full-width pill CTA below. */
@media (max-width: 749px) {
  /* Type tokens read LARGER on mobile than desktop, which looks backwards
     at first glance. It's intentional: the form is full-width on small
     screens (no 560px cap to shrink into), Arabic script needs slightly
     more size than Latin for equal perceived legibility, and the original
     merchant complaint was specifically about the mobile/cart view. Reuses
     this existing breakpoint rather than adding a new one. */
  .cod-form,
  .cod-offer,
  .cod-modal,
  .cod-sticky {
    --cod-fs-xs: 15px;
    --cod-fs-sm: 16px;
    --cod-fs-md: 17px;
    --cod-fs-lg: 18px;
    --cod-fs-xl: 20px;
    --cod-fs-2xl: 23px;
    --cod-fs-3xl: 30px;
  }

  /* Touch target: the compact 34px desktop select is fine for a pointer but
     tight for a thumb, and this store is mobile-heavy. Restore a comfortable
     height on small screens. Scoped under .cod-tiers--bars like every other
     rule in that section, so the cards layout live on nahleh is untouched. */
  .cod-tiers--bars .cod-tier__variant-select {
    min-height: 40px;
    font-size: 16px;
  }

  /* iOS zooms the viewport when a focused control is under 16px, which is what
     the note on .cod-field__input above exists to prevent — but the bars
     override drops these selects to 14px and reintroduced it. Also:
     --cod-fs-2xs is absent from the mobile token block above, so it stays 13px
     while every other token grows. These four bars micro-labels are the
     consumers of it. Overridden here rather than by adding the token upstairs,
     because that block is shared with the cards layout live on production. */
  .cod-tiers--bars .cod-tier__popular,
  .cod-tiers--bars .cod-tier__badge,
  .cod-tiers--bars .cod-tier__per-unit,
  .cod-tiers--bars .cod-tier__savings {
    font-size: 14px;
  }

  .cod-modal__panel {
    /* Reclaim line width on small screens. */
    padding: 16px 16px 24px;
  }

  .cod-cartline__remove {
    width: 36px;
    height: 36px;
  }

  .cod-modal__close {
    width: 44px;
    height: 44px;
  }

  .cod-sticky {
    flex-wrap: wrap;
    padding: 10px 12px 12px;
    border-radius: var(--cod-sticky-radius) var(--cod-sticky-radius) 0 0;
  }
  .cod-sticky--top {
    border-radius: 0 0 var(--cod-sticky-radius) var(--cod-sticky-radius);
  }
  .cod-sticky__info {
    order: 1;
    text-align: right;
  }
  .cod-sticky__image {
    order: 2;
  }
  .cod-sticky__cta {
    order: 3;
    width: 100%;
    padding: 12px 16px;
    border-radius: 25px;
    /* Capped at md (not lg) to stay within the +1-2px mobile growth
       budget — the CTA's font-size is the biggest single driver of the
       bar's total height. */
    font-size: var(--cod-fs-md, 17px);
    line-height: 1.3;
  }

  .cod-sticky--devices-mobile {
    display: flex;
  }
  .cod-sticky--devices-both {
    display: flex;
  }
}

/* Desktop bar — single horizontal row. */
@media (min-width: 750px) {
  .cod-sticky {
    padding: 12px 24px;
    border-radius: var(--cod-sticky-radius);
    max-width: 720px;
    margin-inline: auto;
    inset-inline: 0;
  }
  .cod-sticky--bottom {
    margin-bottom: 16px;
  }
  .cod-sticky--top {
    margin-top: 16px;
  }
  .cod-sticky__info {
    flex-direction: row;
    align-items: center;
    gap: 16px;
  }
  .cod-sticky__title {
    max-width: 220px;
  }
  .cod-sticky__cta {
    padding: 10px 28px;
    border-radius: calc(var(--cod-sticky-radius) / 2);
    font-size: var(--cod-fs-md, 16px);
    line-height: 1.3;
  }

  .cod-sticky--devices-desktop {
    display: flex;
  }
  .cod-sticky--devices-both {
    display: flex;
  }
}

/* `money` here is a BUCKS Currency Converter hook — it only converts text
   inside `span.money` — not a styling class. Themes commonly style .money,
   so neutralise it: adding the hook must not restyle a price. */
.cod-form .money,
.cod-sticky .money {
  font: inherit;
  color: inherit;
  display: inline;
  background: none;
}
