/* themes/naqi/assets/base.css — the tiny non-utility sheet for «نقي».
 *
 * Loads AFTER tw.css (layout/theme.liquid). Everything the utilities layer must
 * still beat is wrapped in `@layer base`; the few deliberate overrides (focus
 * ring, motion gates) are unlayered on purpose and say so.
 *
 * ONLY what utilities cannot express lives here: the document defaults, the
 * skip link, the Ledger section seam, the islands-runtime price bridge, the
 * toast dressing, the scroll reveal, and motion gating.
 */

@layer base {
  /* The document face. The root stays at the browser default (16px) so every
     Tailwind utility maps 1:1 to a pixel measured off the Pencil refs — this
     theme has no base-size slider to anchor there, unlike its two siblings.
     BODY carries the BLUEPRINT's reading setting instead (17px / 1.8): prose
     that names no `text-*` utility gets the Arabic measure it was designed for,
     and anything that does name one is unaffected. */
  body {
    font-family: var(--nq-font-body);
    font-size: 1.0625rem;
    line-height: 1.8;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }

  /* Arabic is a CONNECTED script — letterspacing breaks the joins and is never
     a hierarchy device here. Declared once, at the root of the cascade, so no
     section has to remember it and an inherited `tracking-*` from anywhere
     cannot leak into a heading. Hierarchy is size jump plus weight. */
  :where(h1, h2, h3, h4, h5, h6) {
    font-family: var(--nq-font-heading);
    letter-spacing: 0;
    color: var(--nq-heading);
  }

  /* Skip link — off-screen until focused, then pinned to the top. */
  .nq-skip {
    position: absolute;
    inset-block-start: -100%;
    inset-inline-start: 0;
    z-index: 100;
    padding: 0.625rem 1.25rem;
    background: var(--nq-primary-bg);
    color: var(--nq-primary-text);
  }

  .nq-skip:focus {
    inset-block-start: 0;
  }

  /* ---- THE LEDGER SEAM ---------------------------------------------------
     The identity rule. Adjacent modules SHARE a border so the page reads as one
     ruled table rather than a stack of floating cards — that is the whole of
     «مسطرة», and it is a theme constant, never a merchant setting.

     It is an opt-in CLASS rather than an `section + section` rule because the
     platform renders sections BARE — there is no per-section wrapper element to
     select between (unlike Shopify's `#shopify-section-*`), so a sibling
     combinator would have nothing reliable to match and would also catch the
     bands that must NOT be seamed. Every ordinary section root carries
     `nq-seam`; sections that paint their own field (the announcement strip, the
     footer) simply do not, because a hairline inside an ink slab is invisible at
     best and a smudge at worst.

     THE FIRST BAND ON A PAGE IS THE EXCEPTION, and it is handled here rather
     than by the section, which has no way to know it is first. The header
     already drew that line under itself; without this suppression the join
     carries two hairlines a pixel apart, which is the doubled-rule artefact the
     whole convention exists to avoid. */
  .nq-seam {
    border-block-start: 1px solid var(--nq-border);
  }

  #nq-main > .nq-seam:first-child {
    border-block-start: 0;
  }

  /* ---- islands-runtime price bridge -----------------------------------
     The product-price island swaps its inner markup on every variant change and
     re-emits the RUNTIME's own price vocabulary — ez-b-price__now / __was plus
     ez-u-sr-only labels — classes tw.css never sees, so no utility styles them.
     Without this bridge a swapped price loses the theme's typography and the
     screen-reader labels leak as visible text.

     Mapped onto the Ledger look: the number is INK in the heading face with
     TABULAR figures (every price and quantity in this theme is tabular, so a
     column of them aligns on the decimal), and the strike is muted. The SALE
     price is the one place accent is spent on a price — part of the 2% budget. */
  .ez-b-price__now {
    font-family: var(--nq-font-heading);
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 1.5rem;
    line-height: 1.2;
    color: var(--nq-heading);
  }

  .ez-b-price__now--sale {
    color: var(--nq-accent);
  }

  .ez-b-price__was {
    margin-inline-start: 0.5rem;
    font-variant-numeric: tabular-nums;
    font-size: 1rem;
    font-weight: 400;
    color: var(--nq-text-muted);
    text-decoration: line-through;
  }

  @media (width >= 64rem) {
    .ez-b-price__now {
      font-size: 1.75rem;
    }
  }

  /* Price-gated shops keep the Ledger vocabulary: a dashed hairline chip at
     every price site, a full-width ruled panel on the PDP, and the two static
     approval notices. The island only reveals these theme-authored states. */
  .nq-price-mask {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.35rem 0.7rem;
    border: 1px dashed var(--nq-border);
    background: var(--nq-page-bg);
    color: var(--nq-text-muted);
    font-family: var(--nq-font-heading);
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.5;
  }

  .nq-price-mask__icon {
    flex: none;
    font-size: 0.85rem;
  }

  .nq-price-lock {
    flex-basis: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 1.4rem;
    border: 1px dashed var(--nq-border);
    background: var(--nq-page-bg);
  }

  .nq-price-lock b {
    font-family: var(--nq-font-heading);
    font-weight: 700;
  }

  .nq-price-lock p {
    color: var(--nq-text-muted);
    font-size: 0.85rem;
  }

  .nq-price-lock__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 3rem;
    padding-inline: 1.5rem;
    border: 1px solid var(--nq-primary-bg);
    background: var(--nq-primary-bg);
    color: var(--nq-primary-text);
    font-family: var(--nq-font-heading);
    font-size: 0.95rem;
    font-weight: 700;
    transition:
      background-color 150ms ease-out,
      border-color 150ms ease-out;
  }

  .nq-price-lock__action:hover {
    border-color: var(--nq-accent);
    background: var(--nq-accent);
  }

  .nq-price-banner {
    flex-basis: 100%;
    display: flex;
    align-items: flex-start;
    gap: 0.8rem;
    padding: 1rem;
    border: 1px solid var(--nq-border);
    background: var(--nq-placeholder-bg);
    font-size: 0.95rem;
  }

  .nq-price-banner__icon {
    flex: none;
    display: grid;
    place-items: center;
    inline-size: 2.2rem;
    block-size: 2.2rem;
    border: 1px solid var(--nq-border);
    background: var(--nq-surface-bg);
  }

  .nq-price-banner :where(b, strong) {
    display: block;
    font-family: var(--nq-font-heading);
    font-weight: 700;
  }

  .nq-price-banner p {
    color: var(--nq-text-muted);
    font-size: 0.88rem;
  }

  .nq-price-banner a {
    color: var(--nq-accent);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 4px;
  }

  /* Stable PDP target for card «اشترِ الآن» links. The offset clears the sticky
     header; smooth fragment navigation stays an enhancement and is disabled by
     the visitor's reduced-motion preference below. */
  .nq-buy-anchor {
    scroll-margin-block-start: 6rem;
  }

  .ez-u-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  /* ---- toast ----------------------------------------------------------
     What the shared islands runtime (ez-islands.js initToast) renders on cart
     events. The runtime is theme-agnostic (class hooks only, no colours); this
     is where «نقي» dresses it — a square ink slab with a vermilion edge and NO
     shadow, because this theme has none anywhere. Pinned block-end /
     inline-start (bottom-right in RTL). */
  .ez-toast-region {
    position: fixed;
    inset-block-end: 1.25rem;
    inset-inline-start: 1.25rem;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: min(21rem, calc(100% - 2.5rem));
    pointer-events: none;
  }

  .ez-toast {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1.125rem;
    background: var(--nq-primary-bg);
    color: var(--nq-primary-text);
    border-inline-start: 3px solid var(--nq-accent);
    font-family: var(--nq-font-heading);
    font-size: 0.875rem;
    line-height: 1.5;
    pointer-events: auto;
    animation: nq-toast-in 220ms cubic-bezier(0.2, 0, 0, 1) both;
  }

  .ez-toast.is-leaving {
    animation: nq-toast-out 180ms ease forwards;
  }

  .ez-toast--error {
    border-inline-start-color: var(--nq-accent);
  }

  .ez-toast__msg {
    flex: 1;
  }

  .ez-toast__action {
    flex-shrink: 0;
    font-weight: 700;
    color: var(--nq-primary-text);
    white-space: nowrap;
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: opacity 150ms ease;
  }

  .ez-toast__action:hover {
    opacity: 0.75;
  }
}

/* Card media arrows are created by the shared island only when two frames exist.
   Hairline, square, no shadow: the Ledger treatment. They clear the overlay link
   and commerce controls, use logical inset properties, and remain visible where
   hover cannot reveal them. */
.az-card-arrow {
  position: absolute;
  z-index: 30;
  inset-block-start: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  inline-size: 2.125rem;
  block-size: 2.125rem;
  /* A disc, not a rounded square: the card is already a grid of rectangles and
     the media box has its own corner radius, so another small rounded box
     reads as a mis-sized tile. The circle is the one shape that isn't
     competing with anything else on the card. Still a hairline, still no
     shadow — Ledger. */
  border: 1px solid var(--nq-border);
  border-radius: 50%;
  background: color-mix(in oklab, var(--nq-surface-bg) 92%, transparent);
  color: var(--nq-heading);
  opacity: 0;
  transition:
    opacity 150ms ease-out,
    background-color 150ms ease-out,
    border-color 150ms ease-out;
}

.az-card-arrow:hover {
  background: var(--nq-surface-bg);
  border-color: var(--nq-heading);
}

/* PHYSICAL borders on purpose — do not "modernise" these to logical ones.
   This is a rotated GLYPH, not text-flow content: the two strokes have to meet
   at a known corner for the rotate values below to aim it. With
   `border-inline-start` the corner flips to the top-RIGHT under `dir="rtl"`,
   which turns the same rotations into up/down chevrons instead of left/right.
   The arrows' POSITIONS stay logical, which is where direction-awareness
   actually belongs. */
.az-card-arrow::before {
  content: '';
  inline-size: 0.5rem;
  block-size: 0.5rem;
  border-left: 1.5px solid currentColor;
  border-top: 1.5px solid currentColor;
}

/* THE ARROWS MUST POINT OUTWARD, AWAY FROM THE CARD'S CENTRE — two chevrons
   aimed at each other read as "collapse", not "browse".
   In RTL the track runs right-to-left: the first image sits on the RIGHT, so
   «previous» lives on the right edge pointing right, and «next» on the left
   edge pointing left. `inline-start` IS the right edge here, which is the trap
   — these were reversed, putting «previous» on the left. */
.az-card-arrow--prev {
  inset-inline-start: 0.625rem;
}

.az-card-arrow--prev::before {
  rotate: 135deg;
  /* The rotated corner's visual mass sits opposite its vertex; nudge it back
     so the chevron looks centred in the disc rather than measured-centred. */
  translate: -0.0625rem 0;
}

.az-card-arrow--next {
  inset-inline-end: 0.625rem;
}

.az-card-arrow--next::before {
  rotate: -45deg;
  translate: 0.0625rem 0;
}

.group:hover .az-card-arrow,
.group:focus-within .az-card-arrow {
  opacity: 1;
}

.nq-card-variants[open] {
  display: block;
}

@media (hover: none) {
  .az-card-arrow {
    opacity: 1;
  }
}

/* Keyboard focus ring — a deliberate a11y override, UNLAYERED so it beats any
   control's `focus:outline-none` utility. Drawn in ACCENT: this is one of the
   four sanctioned spends of the vermilion budget, and on a theme built entirely
   from grey hairlines it is the only ring that reads at a glance. Scoped to
   :focus-visible, so a pointer click keeps the quiet border. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--nq-accent);
  outline-offset: 2px;
}

/* ---- scroll reveal ----------------------------------------------------
   Sections opt in with `nq-reveal`; assets/nq-motion.js adds `is-armed` (only
   after confirming motion is allowed) and then `is-in` on first intersection.

   THE SETTLED STATE IS THE BASE DECLARATION, and that inversion is the point:
   no JS, a blocked asset, a module error, reduced motion, the editor canvas —
   every path that ends without the script running leaves content VISIBLE. The
   older idiom staged `opacity: 0` in CSS and depended on JS to undo it, which
   made a script failure indistinguishable from "hide this forever". There is
   nothing to rescue here, so there is no failsafe timer.

   Ledger is a STILL theme (BLUEPRINT §Motion): a short fade and rise, and that
   is the entire animated surface. No marquee, no parallax, no hover lifts —
   hover is a tint or an underline. */
.nq-reveal {
  opacity: 1;
}

.nq-reveal.is-armed {
  opacity: 0;
  transform: translateY(10px);
}

.nq-reveal.is-armed.is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity 460ms cubic-bezier(0.2, 0, 0, 1),
    transform 460ms cubic-bezier(0.2, 0, 0, 1);

  /* On the SETTLED rule, not the armed one, so it delays the journey in and
     never the arming — an element armed late would otherwise sit invisible for
     its own delay before it even began. */
  transition-delay: var(--nq-reveal-delay, 0ms);
}

@keyframes nq-toast-in {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes nq-toast-out {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(0.375rem);
  }
}

/* THERE IS NO `animations_enabled` GLOBAL HERE, and its absence is a decision
   rather than an omission — its two siblings both ship one.

   The BLUEPRINT's settings budget is a hard cap ("Nothing else global"), and
   this theme's entire animated surface is one 460ms fade-and-rise. A merchant
   toggle to switch off a single subtle reveal buys a control panel row and
   almost nothing else, and every setting in this theme has to earn its place.
   What remains is the gate that actually matters: the visitor's own OS
   preference, honoured below in CSS and re-read in nq-motion.js — which also
   declines to arm the reveal on a low-power device.

   Add a global motion toggle later and it needs BOTH halves: a body class
   blanket here (`animation/transition: none !important`) and the same class
   re-read in nq-motion.js, because `!important` silences CSS but cannot touch a
   WAAPI animation. */

/* DESIGN MODE IS NOT A BLANKET — it suppresses AMBIENT (looping) motion only,
   for an editorial reason rather than an aesthetic one: looping motion moves
   selectable targets under the merchant's cursor while they are trying to click
   them. Shopify does not gate animation on `design_mode` either.

   Suppression is by ANIMATION NAME, never by wildcard, because a wildcard also
   kills the one-shot reveal — which is precisely how sections elsewhere ended
   up permanently blank in the canvas. «نقي» currently ships NO infinite
   keyframe: every animation here is one-shot. Add one and it must be named in a
   rule below, or it will loop under the merchant's cursor. */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* generated: checkout-form-design-bridge:start */
/* Form-owned checkout presentation is deliberately sparse. A var() whose
 * custom property is missing does NOT reveal a lower declaration in the
 * cascade; it makes the winning declaration compute to its initial value.
 * Guard every property by its literal presence in the generated style so an
 * inherited or partially customised form retains the theme's authored chrome. */
[data-ez-checkout-form][style*='--ez-checkout-form-bg:'] {
  background-color: var(--ez-checkout-form-bg);
}

[data-ez-checkout-form][style*='--ez-checkout-form-border:'] {
  border-color: var(--ez-checkout-form-border);
}

[data-ez-checkout-form][style*='--ez-checkout-form-border-width:'] {
  border-style: solid;
  border-width: var(--ez-checkout-form-border-width);
}

[data-ez-checkout-form][style*='--ez-checkout-form-radius:'] {
  border-radius: var(--ez-checkout-form-radius);
}

[data-ez-checkout-form][style*='--ez-checkout-form-padding:'] {
  padding: var(--ez-checkout-form-padding);
}

[data-ez-checkout-form][style*='--ez-checkout-font-family:'] {
  font-family: var(--ez-checkout-font-family);
}

[data-ez-checkout-form][style*='--ez-checkout-row-gap:']
  [data-ez-checkout-fields] {
  row-gap: var(--ez-checkout-row-gap);
}

[data-ez-checkout-form][style*='--ez-checkout-column-gap:']
  [data-ez-checkout-fields] {
  column-gap: var(--ez-checkout-column-gap);
}

[data-ez-checkout-form][style*='--ez-checkout-label-color:']
  :is([data-ez-checkout-label], label, legend) {
  color: var(--ez-checkout-label-color);
}

[data-ez-checkout-form][style*='--ez-checkout-label-size:']
  :is([data-ez-checkout-label], label, legend) {
  font-size: var(--ez-checkout-label-size);
}

[data-ez-checkout-form][style*='--ez-checkout-label-weight:']
  :is([data-ez-checkout-label], label, legend) {
  font-weight: var(--ez-checkout-label-weight);
}

[data-ez-checkout-form][style*='--ez-checkout-control-height:']
  :is(
    [data-ez-checkout-control]:not(textarea),
    input:not([type='hidden']):not([type='radio']):not([type='checkbox']),
    select
  ) {
  height: var(--ez-checkout-control-height);
  min-height: 0;
  padding-block: 0;
}

[data-ez-checkout-form][style*='--ez-checkout-control-height:'] textarea {
  min-height: var(--ez-checkout-control-height);
}

[data-ez-checkout-form][style*='--ez-checkout-control-text:']
  :is(
    [data-ez-checkout-control],
    input:not([type='hidden']):not([type='radio']):not([type='checkbox']),
    select,
    textarea
  ) {
  color: var(--ez-checkout-control-text);
}

[data-ez-checkout-form][style*='--ez-checkout-control-bg:']
  :is(
    [data-ez-checkout-control],
    input:not([type='hidden']):not([type='radio']):not([type='checkbox']),
    select,
    textarea
  ) {
  background-color: var(--ez-checkout-control-bg);
}

[data-ez-checkout-form][style*='--ez-checkout-control-border:']
  :is(
    [data-ez-checkout-control],
    input:not([type='hidden']):not([type='radio']):not([type='checkbox']),
    select,
    textarea
  ) {
  border-color: var(--ez-checkout-control-border);
}

[data-ez-checkout-form][style*='--ez-checkout-control-radius:']
  :is(
    [data-ez-checkout-control],
    input:not([type='hidden']):not([type='radio']):not([type='checkbox']),
    select,
    textarea
  ) {
  border-radius: var(--ez-checkout-control-radius);
}

[data-ez-checkout-form][style*='--ez-checkout-control-size:']
  :is(
    [data-ez-checkout-control],
    input:not([type='hidden']):not([type='radio']):not([type='checkbox']),
    select,
    textarea
  ) {
  font-size: var(--ez-checkout-control-size);
}

[data-ez-checkout-form][style*='--ez-checkout-placeholder:']
  :is([data-ez-checkout-control], input, textarea)::placeholder {
  color: var(--ez-checkout-placeholder);
}

[data-ez-checkout-form][style*='--ez-checkout-choice-accent:']
  :is([data-ez-checkout-choice], input[type='radio'], input[type='checkbox']) {
  accent-color: var(--ez-checkout-choice-accent);
}

[data-ez-checkout-form][style*='--ez-checkout-choice-accent:']
  [data-ez-checkout-choice]:checked {
  border-color: var(--ez-checkout-choice-accent);
  background-color: var(--ez-checkout-choice-accent);
}

[data-ez-checkout-form][style*='--ez-checkout-choice-accent:']
  input:checked
  + [data-ez-checkout-choice-indicator] {
  border-color: var(--ez-checkout-choice-accent);
}

[data-ez-checkout-form][style*='--ez-checkout-choice-accent:']
  [data-ez-checkout-choice]:has(input:checked) {
  border-color: var(--ez-checkout-choice-accent);
}

[data-ez-checkout-form][style*='--ez-checkout-choice-accent:']
  input:checked
  + [data-ez-checkout-choice-indicator]
  > span {
  background-color: var(--ez-checkout-choice-accent);
}

[data-ez-checkout-form][style*='--ez-checkout-helper:']
  [data-ez-checkout-helper] {
  color: var(--ez-checkout-helper);
}

[data-ez-checkout-form][style*='--ez-checkout-error:']
  :is([data-ez-checkout-error], [data-ez-field-error]) {
  color: var(--ez-checkout-error);
}

[data-ez-checkout-form][style*='--ez-checkout-error:']
  :is(input, select, textarea):user-invalid {
  border-color: var(--ez-checkout-error);
}

[data-ez-checkout-submit][style*='--ez-checkout-button-height:'],
[data-ez-checkout-form][style*='--ez-checkout-button-height:']
  button[type='submit'] {
  height: var(--ez-checkout-button-height);
  min-height: 0;
  padding-block: 0;
}

[data-ez-checkout-submit][style*='--ez-checkout-button-text:'],
[data-ez-checkout-form][style*='--ez-checkout-button-text:']
  button[type='submit'] {
  color: var(--ez-checkout-button-text);
}

[data-ez-checkout-submit][style*='--ez-checkout-button-bg:'],
[data-ez-checkout-form][style*='--ez-checkout-button-bg:']
  button[type='submit'] {
  background-color: var(--ez-checkout-button-bg);
}

[data-ez-checkout-submit][style*='--ez-checkout-button-radius:'],
[data-ez-checkout-form][style*='--ez-checkout-button-radius:']
  button[type='submit'] {
  border-radius: var(--ez-checkout-button-radius);
}

[data-ez-checkout-submit][style*='--ez-checkout-button-size:'],
[data-ez-checkout-form][style*='--ez-checkout-button-size:']
  button[type='submit'] {
  font-size: var(--ez-checkout-button-size);
}

[data-ez-checkout-submit][style*='--ez-checkout-button-weight:'],
[data-ez-checkout-form][style*='--ez-checkout-button-weight:']
  button[type='submit'] {
  font-weight: var(--ez-checkout-button-weight);
}

@media (min-width: 48rem) {
  [data-ez-checkout-fields][data-ez-checkout-layout='true'] {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }

  [data-ez-checkout-fields][data-ez-checkout-layout='true']
    > [data-ez-checkout-field] {
    grid-column: span var(--ez-checkout-span, 12) / span
      var(--ez-checkout-span, 12);
  }
}
/* generated: checkout-form-design-bridge:end */
