/* =============================================================================================
   Card themes + card ground — ONE file, served by BOTH apps.

   Why it is not in souq.css: there are two souq.css files, one per app, and they had already
   drifted. The public one carried the whole ground system (patterns, background image, the
   stacking rule); the business one carried none of it and a stale copy of the theme tokens.
   The builder preview loads the BUSINESS stylesheet, so an owner who picked a pattern saw the
   preview not change — the feature existed and was invisible at the one moment it had to be
   visible.

   Souq.Web.Business links this file out of the public project (see its .csproj), so there is
   exactly one definition of what a card looks like and the two apps cannot disagree again.

   Everything here is additive for cards already published: every consumption site is written
   var(--c-x, <fallback>), a card with no stored pattern gets no class, and a card with no
   background image gets no layer.
   ============================================================================================= */

/* ---------------------------------- theme token sets ---------------------------------------- */
/* A theme controls not just colour but the whole look: corner radius, border weight, surface
   elevation, section spacing and heading treatment. */

.card-theme-emerald { --c-bg:#f7faf8; --c-surface:#fff; --c-text:#15241d; --c-muted:#5b6b63; --c-primary:#0e8c5b; --c-primary-fg:#fff; --c-accent:#f5b544; --c-accent-fg:#3a2c00; --c-border:#e4ece8;
  --c-radius:16px; --c-border-w:1px; --c-shadow:0 8px 22px -12px rgba(14,140,91,.35); --c-space:12px; }

.card-theme-noir { --c-bg:#121212; --c-surface:#1c1c1c; --c-text:#f3ead0; --c-muted:#b6a98a; --c-primary:#c9a84c; --c-primary-fg:#121212; --c-accent:#e7c873; --c-accent-fg:#121212; --c-border:rgba(255,255,255,.12);
  --c-radius:12px; --c-border-w:1px; --c-shadow:0 10px 30px -10px rgba(0,0,0,.7); --c-space:12px; --c-heading-spacing:.02em; }

/* Cream: warm, generously rounded, soft airy elevation. */
.card-theme-cream { --c-bg: oklch(0.97 0.015 75); --c-surface: oklch(0.99 0.008 75); --c-text: oklch(0.22 0.04 50); --c-muted: oklch(0.5 0.03 50); --c-primary: oklch(0.48 0.08 50); --c-primary-fg: oklch(0.99 0.01 70); --c-accent: oklch(0.7 0.1 55); --c-accent-fg: oklch(0.18 0.04 50); --c-border: oklch(0.88 0.02 70);
  --c-radius:22px; --c-border-w:1px; --c-shadow:0 12px 34px -14px oklch(0.48 0.08 50 / .32); --c-space:14px; }

/* Aurora: dark, glassy, neon glow around every surface. */
.card-theme-aurora { --c-bg: oklch(0.16 0.04 270); --c-surface: oklch(0.22 0.05 265); --c-text: oklch(0.97 0.01 270); --c-muted: oklch(0.72 0.03 270); --c-primary: oklch(0.78 0.18 155); --c-primary-fg: oklch(0.14 0.04 270); --c-accent: oklch(0.72 0.17 305); --c-accent-fg: oklch(0.14 0.04 270); --c-border: oklch(1 0 0 / 14%);
  --c-radius:18px; --c-border-w:1px; --c-shadow:0 0 0 1px oklch(1 0 0 / .05), 0 10px 34px -8px oklch(0.78 0.18 155 / .4); --c-space:13px; }

/* Brutal: no radius, thick black borders, hard offset shadow, uppercase headings. */
.card-theme-brutal { --c-bg: oklch(1 0 0); --c-surface: oklch(1 0 0); --c-text: oklch(0.12 0 0); --c-muted: oklch(0.35 0 0); --c-primary: oklch(0.12 0 0); --c-primary-fg: oklch(1 0 0); --c-accent: oklch(0.68 0.22 35); --c-accent-fg: oklch(1 0 0); --c-border: oklch(0.12 0 0);
  --c-radius:0px; --c-border-w:2px; --c-shadow:5px 5px 0 0 oklch(0.12 0 0); --c-space:14px; --c-heading-transform:uppercase; --c-heading-spacing:.01em; }

/* Every --c-primary below clears WCAG AA (4.5:1) against white, so a white-on-primary button
   stays legible: azure 5.17, violet 5.70, sunset 5.18, slate 17.74. */
/* Azure: crisp and corporate — tight radius, cool grey ground, restrained elevation. */
.card-theme-azure { --c-bg:#f5f7fa; --c-surface:#fff; --c-text:#111827; --c-muted:#6b7280; --c-primary:#2563eb; --c-primary-fg:#fff; --c-accent:#f59e0b; --c-accent-fg:#3a2c00; --c-border:#e2e8f0;
  --c-radius:12px; --c-border-w:1px; --c-shadow:0 6px 18px -10px rgba(37,99,235,.35); --c-space:12px; }

/* Violet: elegant — borderless surfaces, generous radius, diffuse lift. */
.card-theme-violet { --c-bg:#faf9fe; --c-surface:#fff; --c-text:#1f2937; --c-muted:#6b7280; --c-primary:#7c3aed; --c-primary-fg:#fff; --c-accent:#a855f7; --c-accent-fg:#fff; --c-border:#e9e5f5;
  --c-radius:20px; --c-border-w:0px; --c-shadow:0 16px 40px -18px rgba(124,58,237,.45); --c-space:15px; }

/* Sunset: warm market palette — soft rounding, sandy ground, glowing accent. */
.card-theme-sunset { --c-bg:#fff7ed; --c-surface:#fff; --c-text:#7c2d12; --c-muted:#9a6b4f; --c-primary:#c2410c; --c-primary-fg:#fff; --c-accent:#f97316; --c-accent-fg:#43180a; --c-border:#fbe3ce;
  --c-radius:18px; --c-border-w:1px; --c-shadow:0 10px 28px -14px rgba(194,65,12,.4); --c-space:14px; }

/* Slate: minimal — hairline borders, no shadow, near-black primary. */
.card-theme-slate { --c-bg:#f3f4f6; --c-surface:#fff; --c-text:#111827; --c-muted:#6b7280; --c-primary:#111827; --c-primary-fg:#fff; --c-accent:#374151; --c-accent-fg:#fff; --c-border:#e5e7eb;
  --c-radius:8px; --c-border-w:1px; --c-shadow:none; --c-space:12px; --c-heading-spacing:.01em; }

/* Petrol: deep teal ground under a champagne accent, generous spacing. The pairing a textured
   ground reads best on, and the one theme designed from the start to be seen WITH a ground. */
.card-theme-petrol { --c-bg:#012e38; --c-surface:#06404c; --c-text:#f4efe6; --c-muted:#a6bcc1; --c-primary:#c4a780; --c-primary-fg:#04232b; --c-accent:#e3c89a; --c-accent-fg:#04232b; --c-border:rgba(244,239,230,.15);
  --c-radius:14px; --c-border-w:1px; --c-shadow:0 14px 34px -16px rgba(0,0,0,.65); --c-space:16px; }

/* ------------------------------------ the ground layer -------------------------------------- */
/* Painted on ::before of the card root rather than on the root's own background, so --c-bg keeps
   doing exactly what it did and the ground sits on top of it. position:fixed keeps the texture
   still while the card scrolls, which reads as ground rather than as wallpaper glued to the
   content — and costs nothing, since the layer never repaints.

   Three things the ground did not have before, and which are what separated ours from a ground
   that reads as material:
     --c-pattern-scale   the tile size. A texture at the wrong scale reads as noise at one end
                         and as wallpaper at the other; it is the single most consequential
                         value here and there was no way to set it.
     --c-pattern-color   the tile colour, defaulting to the card's text colour as before. A
                         ground in the accent colour is a different design, not a darker one.
     --c-ground-opacity  a per-ground default, because a hairline weave and a bold zellij do not
                         read at the same strength. The owner's --c-pattern-opacity still wins. */
[class*="card-pattern-"]::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: calc(var(--c-pattern-opacity, var(--c-ground-opacity, 6)) * 1%);
  color: var(--c-pattern-color, var(--c-text));
}

/* Content sits above both layers. Scoped to the card root's children so nothing else on the page
   inherits a stacking context it did not ask for. The second selector reaches through the band
   wrapper, which is `display: contents` and therefore not a box of its own. */
.js-card-root > *,
.js-card-root > .card-band > * { position: relative; z-index: 1; }

/* ------------------------------------ alternating bands ------------------------------------- */
/* Every section is wrapped, always — but the wrapper is `display: contents`, so on a card with no
   bands it is not a box at all and layout, margins and margin-collapsing behave exactly as they
   did before the wrapper existed. Only when the owner turns bands on does every other wrapper
   become a real block.

   :has(> .psection) is doing real work: several section types render nothing when they hold no
   content (testimonials with no quotes, a video with no url), and their wrapper must stay
   invisible rather than paint an empty stripe.

   The tint is translucent on purpose — a band layers OVER the card's ground instead of hiding it,
   so texture and rhythm compose. It is mixed from --c-text, which means one value reads correctly
   on a cream theme and on a near-black one. */
.card-band { display: contents; }

.card-band.is-band:has(> .psection) {
  /* flow-root, so the section's own top margin is contained by the band instead of escaping it
     and leaving the stripe hugging the text. */
  display: flow-root;
  margin-block-start: calc(24px + var(--c-space, 12px));
  padding-block: calc(var(--c-space, 12px) + 8px);
}
/* That margin now belongs to the band; leaving it on the section too would double the gap. */
.card-band.is-band:has(> .psection) > .psection { margin-block-start: 0; }

.card-bands-soft   .card-band.is-band:has(> .psection) { background-color: color-mix(in srgb, var(--c-text) 4%, transparent); }
.card-bands-strong .card-band.is-band:has(> .psection) { background-color: color-mix(in srgb, var(--c-text) 9%, transparent); }

/* ---- materials: grounds that read as a surface rather than as a drawn pattern --------------- */
/* Each layer's weight is set with color-mix rather than a second opacity, so the whole ground
   still scales with one --c-pattern-opacity. */

/* Linen — two fine thread grids meeting. High enough in frequency that it never competes with
   type, which makes it the safe default under long copy. */
.card-pattern-linen::before {
  --gs: var(--c-pattern-scale, 4px);
  --c-ground-opacity: 14;
  background-image:
    repeating-linear-gradient(90deg, color-mix(in srgb, currentColor 55%, transparent) 0 1px, transparent 1px var(--gs)),
    repeating-linear-gradient(0deg,  color-mix(in srgb, currentColor 40%, transparent) 0 1px, transparent 1px var(--gs));
  background-size: var(--gs) var(--gs);
}

/* Twill — diagonal weave, two passes at different weights so it gains depth instead of reading
   as a flat hatch. The closest CSS equivalent of a woven cloth texture. */
.card-pattern-twill::before {
  --gs: var(--c-pattern-scale, 14px);
  --c-ground-opacity: 13;
  background-image:
    repeating-linear-gradient(45deg,  color-mix(in srgb, currentColor 60%, transparent) 0 2px, transparent 2px calc(var(--gs) / 2)),
    repeating-linear-gradient(-45deg, color-mix(in srgb, currentColor 35%, transparent) 0 2px, transparent 2px calc(var(--gs) / 2));
  background-size: var(--gs) var(--gs);
}

/* Paper grain — three dot layers at coprime scales, so the eye never finds the repeat. That is
   what makes it read as paper rather than as a grid of dots. */
.card-pattern-paper::before {
  --gs: var(--c-pattern-scale, 37px);
  --c-ground-opacity: 16;
  background-image:
    radial-gradient(circle at 20% 30%, color-mix(in srgb, currentColor 50%, transparent) 0 1px,   transparent 1.6px),
    radial-gradient(circle at 70% 60%, color-mix(in srgb, currentColor 40%, transparent) 0 1.4px, transparent 2px),
    radial-gradient(circle at 45% 85%, color-mix(in srgb, currentColor 45%, transparent) 0 1px,   transparent 1.6px);
  background-size:
    var(--gs) calc(var(--gs) * 1.11),
    calc(var(--gs) * 1.43) calc(var(--gs) * 1.59),
    calc(var(--gs) * .78) calc(var(--gs) * .84);
}

/* Contour lines — the one ground with direction and movement. Reads as a map, which is why it
   suits tourism, property and anything that wants to feel like a place. */
.card-pattern-topo::before {
  --gs: var(--c-pattern-scale, 300px);
  --c-ground-opacity: 15;
  background-image: repeating-radial-gradient(circle at 50% 118%,
    transparent 0 calc(var(--gs) * .12),
    color-mix(in srgb, currentColor 60%, transparent) calc(var(--gs) * .12) calc(var(--gs) * .125),
    transparent calc(var(--gs) * .125) calc(var(--gs) * .246));
  background-size: var(--gs) calc(var(--gs) * .7);
}

/* Zellij — the geometric motif, now in two tones: a dense grid in the primary colour and a wide
   one in the accent. Two colours is the difference between a motif and a texture. */
.card-pattern-zellij::before {
  --gs: var(--c-pattern-scale, 30px);
  --c-ground-opacity: 22;
  color: var(--c-pattern-color, var(--c-primary));
  background-image:
    repeating-linear-gradient(45deg,  color-mix(in srgb, currentColor 45%, transparent) 0 1.5px, transparent 1.5px var(--gs)),
    repeating-linear-gradient(-45deg, color-mix(in srgb, currentColor 45%, transparent) 0 1.5px, transparent 1.5px var(--gs)),
    repeating-linear-gradient(0deg,   color-mix(in srgb, var(--c-accent) 32%, transparent) 0 1.5px, transparent 1.5px calc(var(--gs) * 2)),
    repeating-linear-gradient(90deg,  color-mix(in srgb, var(--c-accent) 32%, transparent) 0 1.5px, transparent 1.5px calc(var(--gs) * 2));
}

/* Soft glow — not a tile at all but three large blooms in the card's own colours. Depth without
   texture, and the safest ground for text because it has no edges anywhere. Scale does not
   apply. */
.card-pattern-mesh::before {
  --c-ground-opacity: 100;
  background-image:
    radial-gradient(58% 38% at 18% 2%,  color-mix(in srgb, var(--c-primary) 22%, transparent), transparent 72%),
    radial-gradient(48% 32% at 92% 24%, color-mix(in srgb, var(--c-accent)  16%, transparent), transparent 72%),
    radial-gradient(72% 46% at 50% 99%, color-mix(in srgb, var(--c-primary) 14%, transparent), transparent 72%);
  background-repeat: no-repeat;
}

/* ---- the original geometric set, kept so every card already published renders unchanged ----- */
.card-pattern-dots::before {
  --gs: var(--c-pattern-scale, 22px);
  background-image: radial-gradient(currentColor 1.5px, transparent 1.6px);
  background-size: var(--gs) var(--gs);
}
.card-pattern-grid::before {
  --gs: var(--c-pattern-scale, 44px);
  background-image: linear-gradient(currentColor 1px, transparent 1px),
                    linear-gradient(90deg, currentColor 1px, transparent 1px);
  background-size: var(--gs) var(--gs);
}
.card-pattern-diagonal::before {
  --gs: var(--c-pattern-scale, 14px);
  background-image: repeating-linear-gradient(45deg, currentColor 0 2px, transparent 2px var(--gs));
}
.card-pattern-waves::before {
  --gs: var(--c-pattern-scale, 40px);
  background-image: radial-gradient(circle at 50% 100%, transparent calc(var(--gs) * .3), currentColor calc(var(--gs) * .3) calc(var(--gs) * .3375), transparent calc(var(--gs) * .35));
  background-size: var(--gs) calc(var(--gs) / 2);
}
.card-pattern-carbon::before {
  --gs: var(--c-pattern-scale, 4px);
  background-image: repeating-linear-gradient(0deg, currentColor 0 1px, transparent 1px var(--gs));
}

/* --------------------------------- background image ----------------------------------------- */
/* Shown well below the text and veiled, so the copy over it keeps its contrast whatever the
   owner uploads. Fixed for the same reason as the ground.

   Two modes, because they are two different uploads. COVER is a photograph — one image, scaled
   to fill, never repeated. TILE is a seamless texture, and it needs a tile SIZE to be any good;
   forcing a seamless texture through `cover` (the only thing we used to do) blows one thread of
   it up to the width of the screen, which is why uploaded textures never looked like anything. */
.card-bg-image::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--c-bg-image);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: calc(var(--c-bg-image-opacity, 16) * 1%);
}
.card-bgimg-tile::after {
  background-size: var(--c-bg-image-scale, 400px) auto;
  background-repeat: repeat;
  background-position: center top;
}

/* ------------------------------- ground swatch (builder) ------------------------------------ */
/* A swatch in the builder's gallery paints itself with the very same class the published card
   uses, so the picker cannot drift from the product. The only thing it changes is the layer's
   positioning: the card's ground is fixed to the viewport, which inside a 96px tile would cover
   the screen instead of the tile. */
.ground-swatch { position: relative; overflow: hidden; background: var(--c-bg); }
.ground-swatch[class*="card-pattern-"]::before {
  position: absolute;
  background-attachment: scroll;
}

/* A ground is decoration. Anyone who has asked not to be shown motion still gets the colour and
   the image, and mesh is unaffected either way — none of these animate, but a hard-edged tile at
   a small scale can shimmer on scroll for readers sensitive to it. */
@media (prefers-reduced-motion: reduce) {
  [class*="card-pattern-"]::before { background-attachment: scroll; }
}
