/* ===========================================================================
 * DigiDollar - front-page «منظومه» hub ([dd_home_map]).
 * Loads AFTER dd-widgets.css and reuses its tokens (--dd-gold, --dd-card, ...).
 * Light = default - Dark = html[data-dracula-scheme="dark"]
 *
 * MOBILE FIRST. The base rules below are the phone layout; the single
 * `min-width: 860px` block near the end widens the orbit into its landscape
 * form. There is no second layout - only the ellipse ratios change.
 *
 * ---------------------------------------------------------------------------
 * How the constellation is laid out
 * ---------------------------------------------------------------------------
 * One length drives everything: --dd-stage. Every other measurement in the
 * orbit is a multiple of it, so the whole figure scales as one object.
 *
 *   node position = centre + (rx·cos θ, ry·sin θ)
 *
 * PHP emits --cos/--sin per node and --lm/--ld (centre-to-node distance as a
 * fraction of the stage) and --am/--ad (that ray's bearing) per wire. CSS
 * multiplies them by --dd-stage. Switching breakpoint swaps --dd-rx/--dd-ry
 * and which pair of wire variables is live - nothing else moves.
 *
 * Consequences worth keeping: no JS touches layout, nothing recalculates on
 * rotate or resize, and the figure cannot desynchronise from its wires because
 * both are derived from the same numbers.
 *
 * ---------------------------------------------------------------------------
 * House rules observed here
 * ---------------------------------------------------------------------------
 * - No eyebrow pill anywhere. This section carries no heading at all: the page
 *   H1 belongs to [dd_home_hero], which renders directly below it.
 * - No coloured accent bar or rail anywhere. Borders are 1px hairlines in
 *   --dd-card-brd / --dd-hair; emphasis comes from the icon disc, the --dd-tile
 *   tint and type weight.
 * - The wires ARE the drawing, not decoration on a card: they live in their own
 *   sibling layer (.dd-map__wires), never as a ::before on a panel, and they
 *   encode which node is selected.
 * ======================================================================== */

/* ---------- section shell (full-bleed, matching the other dd sections) ---- */

/* Element-qualified on purpose: the dd-coin-box CTA banner puts a `dd-hero`
   FLAG CLASS on <body>, and this file follows the same discipline so a bare
   class selector can never leak onto the body element. */
section.dd-map {
	position: relative;
	box-sizing: border-box;
	/* Scrollbar-safe: 100vw counts the classic scrollbar, so a plain 100vw
	   breakout hangs ~5px past both edges and gives the page a horizontal
	   scrollbar. --dd-sbw is measured once in the <head> (dd_print_scrollbar_width_probe
	   in inc/digidollar-enhancements.php, which explains why CSS cannot do this
	   alone); the 0px fallback keeps the old behaviour where it is unavailable. */
	width: calc(100vw - var(--dd-sbw, 0px)) !important;
	max-width: calc(100vw - var(--dd-sbw, 0px)) !important;
	margin-left: calc(50% - (100vw - var(--dd-sbw, 0px)) / 2) !important;
	margin-right: calc(50% - (100vw - var(--dd-sbw, 0px)) / 2) !important;
	padding: clamp(14px, 2.2vw, 30px) clamp(16px, 4vw, 40px) clamp(34px, 4.4vw, 68px);
	color: var(--dd-ink);
	overflow: hidden;
	isolation: isolate;
}

/* ---------- material tokens (section-scoped) ----------------------------- */

/* dd-widgets.css ships ONE flat hairline for the whole site
   (--dd-card-brd: rgba(255,255,255,.09) in dark) and it dissolves here.
   Measured on the live page: over this section's near-black ground that edge
   is about two levels of luminance, so the four crypto cards read as text
   floating on the page with no card under them, and the console's own edge
   only survives where the aurora happens to sit behind it.

   The rest of the site is fine with that token - its cards sit on lighter
   grounds - so these are LOCAL and nothing outside section.dd-map sees them.

   The vocabulary is unchanged and still the approved one: a 1px hairline, a
   background tint, an icon tile, type weight. What is added is MATERIAL - the
   top-lit fill and the 1px inner highlight that make an edge read as glass
   rather than as a drawn outline. No coloured rail, no accent bar, no single
   emphasised edge: the highlight is white/neutral and runs the full perimeter
   of the shape, the way light does.

   Gold appears in exactly two places and both are state: --m-brd-lit on hover
   or focus, and the lit arc/wire that points at the open panel. */
section.dd-map {
	--m-brd: rgba(28, 22, 4, 0.12);
	--m-brd-lit: rgba(186, 143, 0, 0.45);
	--m-tile: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.66));
	--m-tile-hover: linear-gradient(180deg, rgba(255, 255, 255, 0.97), rgba(253, 184, 55, 0.16));
	--m-hi: inset 0 1px 0 rgba(255, 255, 255, 0.9);
	--m-lift: 0 8px 20px -14px rgba(58, 44, 0, 0.38);
	--m-lift-up: 0 16px 30px -16px rgba(58, 44, 0, 0.48);
	--m-glass: linear-gradient(180deg, rgba(255, 255, 255, 0.76), rgba(255, 255, 255, 0.42));
	--m-spill: rgba(253, 184, 55, 0.16);
	--m-orbit: rgba(150, 112, 0, 0.16);
	--m-wire: rgba(150, 112, 0, 0.26);
	--m-arc: rgba(214, 158, 0, 0.85);
	--m-arc-glow: rgba(253, 184, 55, 0.4);
	/* A vignette, not a wash: the corners of a full-bleed section are where it
	   stops looking like a stage and starts looking like a rectangle. */
	--m-ground: radial-gradient(128% 100% at 50% 36%, rgba(255, 255, 255, 0) 50%, rgba(120, 96, 20, 0.06) 100%);

	/* Where the coin actually is, as a background position on the full-bleed
	   box. Two things read it - the ground's warm pool in dark mode and, at
	   >=1024, the console's spill - so the section is lit from wherever the
	   constellation happens to be at that breakpoint, and both move together
	   when the layout does. Stacked layouts: above the console, centred. */
	--m-lamp: 50% 28%;
}

/* The theme stacks 80px top margins on .epcl-page-wrapper.content and
   #single.content at desktop widths. This section carries its own spacing. */
body.home div.epcl-page-wrapper.content,
body.home div#single.content {
	margin-top: 0 !important;
}

/* Mobile: the theme pulls content up 20px with a negative margin on #header.
   Undo the pull; the padding that clears the capsule itself is the block
   below. */
@media (max-width: 767px) {
	body.home #header {
		margin-bottom: 0 !important;
	}
}

/* ---------- header clearance -------------------------------------------- */

/* The theme's glass capsule overlays the top of the page, and it overhangs its
   own #header box by ~18px (measured: #header ends at 126, the capsule's
   deepest child at 144). This section opens with the orbit - no heading to
   absorb the collision - so the top node ran straight under the capsule.
   These two rules cover every width; the 768-859 band previously had no rule
   at all and collided.

   `html` + `!important` is load-bearing: the site's Additional CSS ships
   `div.text>:first-child:not(blockquote){padding-top:35px!important}`, which
   this section matches at specificity (0,2,2) - a TIE with
   `body.home section.dd-map` - and Additional CSS prints after the enqueued
   stylesheets, so it wins on source order. `html body.home section.dd-map` is
   (0,2,3) and settles it. */
/* The measured numbers, phone (390px viewport, 2026-08-13): the section's own
   border box opens at y=46 and the header's menu-wrapper box closes at y=144,
   with the last VISIBLE pixel of the auth buttons at ~124. So ~98px of the
   padding is header clearance and everything above that is air. On a phone
   that air is expensive - it is subtracted from the one screen the orbit and
   the console have to share - so it is spent down to the last few px of
   breathing room. 88px now, not the original 92: the orbit and its console
   have to close above the fold together (see the console's height in the
   phone block) and this was the cheapest four of the pixels that bought it.
   Do not spend more here without re-measuring against the header - the
   capsule's own box ends at 126 but its auth buttons paint to ~124, and the
   top node has no heading above it to absorb a collision. */
@media (max-width: 767px) {
	html body.home section.dd-map {
		padding-top: 88px !important;
		padding-bottom: 22px !important;
	}
}

@media (min-width: 768px) {
	html body.home section.dd-map {
		padding-top: 118px !important;
	}
}

.dd-map__inner {
	position: relative;
	z-index: 2;
	max-width: 1180px;
	margin-inline: auto;

	/* --dd-stage lives HERE, on the common parent, not on .dd-map__stage.
	   The console is the stage's SIBLING and needs the same number to match
	   its height; declared on the stage it simply does not exist on the
	   console, `calc(var(--dd-stage) * .93)` is invalid there, and the height
	   silently falls back to auto. Same class of bug as the wire variables -
	   a custom property is only visible to the element that declares it and
	   its descendants. */
	--dd-stage: min(330px, calc(100vw - 34px));
}

/* ---------- theme reset -------------------------------------------------- */

/* The theme styles this column as editorial prose: an inline <style> ships
   `h2 { display:flex; text-align:center !important }` with decorative gold
   rules as ::before/::after, `div.text h1..h6 { color: var(--epcl-black) }`
   paints headings navy, and list items keep their disc marker even when the
   <ul> says list-style:none - the marker is set on the <li>. All of it is
   right for an article and wrong for a laid-out section, and the !important
   means specificity alone cannot undo it. Reset once, here.
   (Verified against the live page: without this every entity card carried a
   bullet.)

   This section deliberately contains no heading element at all - the page H1
   lives in [dd_home_hero] directly below - so the heading half of the old
   reset is gone. The panel titles are <p class="dd-map__panel-h"> and get
   their own high-specificity rule further down, because `div.text p` (0,1,2)
   out-specifies a one-class selector here. */
/* The theme leaves this subtree on content-box. That silently broke the
   equal-height columns: the console's `height:100%` resolved to the grid row
   (502px) and then its 24px padding and 1px border were ADDED on top, so its
   border box came out 552px against the orbit's 502px. Border-box also makes
   --dd-node/--dd-core mean the visible size rather than size-plus-border,
   which is what the polar maths assumes. */
.dd-map *,
.dd-map *::before,
.dd-map *::after {
	box-sizing: border-box;
}

.dd-map ul,
.dd-map li {
	list-style: none !important;
	margin: 0;
	padding: 0;
}

.dd-map li {
	display: block;
}

.dd-map li::marker {
	content: "";
}

.dd-map li::before {
	content: none;
}

.dd-map a {
	color: inherit;
}

/* ---------- ambient background ------------------------------------------ */

.dd-map__bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	/* Keep the animated layers from ever invalidating anything outside this
	   box; the section's overflow:hidden already clips the same area. */
	contain: layout paint style;
}

/* The ground the whole constellation sits on. In light mode the page's own
   cream is already the ground and this adds nothing; in dark it is the
   difference between a section and a black rectangle - a shallow warm pool
   under the orbit, and a vignette that closes the two open corners so the
   full-bleed section reads as a lit stage rather than as a slab. */
.dd-map__bg::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--m-ground, none);
}

/* No filter: blur() - the softness is baked into the gradient stops so the
   breathe animation stays compositor-only (transform/opacity) instead of
   re-blurring a large layer every frame. */
.dd-map__aurora {
	position: absolute;
	top: -30%;
	right: -18%;
	width: 74%;
	height: 78%;
	background:
		radial-gradient(closest-side, rgba(253, 184, 55, 0.26), rgba(253, 184, 55, 0.11) 44%, rgba(253, 184, 55, 0.03) 68%, transparent 80%);
	border-radius: 50%;
	will-change: transform, opacity;
	animation: dd-map-breathe 13s ease-in-out infinite;
}

.dd-map__aurora--b {
	top: auto;
	right: auto;
	bottom: -26%;
	left: -20%;
	width: 62%;
	height: 62%;
	background:
		radial-gradient(closest-side, rgba(224, 190, 0, 0.16), rgba(224, 190, 0, 0.05) 52%, transparent 76%);
	animation-duration: 17s;
	animation-direction: reverse;
}

@keyframes dd-map-breathe {
	0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 0.9; }
	50%      { transform: translate3d(0, 2.5%, 0) scale(1.07); opacity: 1; }
}

/* ---------- the stage ---------------------------------------------------- */

/* The phone ellipse is FLATTENED (0.315 tall against 0.395 wide) where it used
   to be nearly circular. On a phone the orbit and the console have to share one
   screen, so height is the scarce resource and width is the free one: spending
   the width the phone already has buys back ~33px of height at no cost to the
   node size. The bearings for this ellipse are --lp/--ap - see the wire block. */
.dd-map__stage {
	--dd-rx: calc(var(--dd-stage) * 0.395);
	--dd-ry: calc(var(--dd-stage) * 0.315);
	--dd-node: calc(var(--dd-stage) * 0.222);
	--dd-node-r: calc(var(--dd-node) / 2);
	--dd-core: calc(var(--dd-stage) * 0.305);
	--dd-core-r: calc(var(--dd-core) / 2);

	position: relative;
	width: var(--dd-stage);
	/* 2 * (ry + node radius), plus a hair. Any smaller and the top and bottom
	   nodes clip; any larger and the console pays for the difference. */
	height: calc(var(--dd-stage) * 0.865);
	margin: 0 auto;
	/* `layout` only, NOT `layout paint`.

	   Paint containment clips every descendant to this box, and the top node
	   stands 2px from the top edge of it - (height/2 - ry - node radius) works
	   out at 0.0065 of the stage on the phone ellipse. So the open node's glow
	   was being sliced off in a straight line above it, on the one node a
	   visitor sees first. Reported from a real phone, 2026-08-21.

	   Layout containment still does the job it was added for: the orbit's size
	   is fixed by width/height above, so nothing inside it can shift the page
	   while the mark decodes. The section's own overflow:hidden is what keeps
	   the glow from escaping the page. */
	contain: layout;
}

/* ---------- wires -------------------------------------------------------- */

.dd-map__wires {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

/* ---------- the orbit path ----------------------------------------------- */

/* The ellipse the six nodes actually stand on, drawn.

   Until now the figure was six discs and six spokes, and a spoke tells you a
   node is attached to the core but not that the six belong to one system. The
   path does: it closes the figure, and it is the reason the arrangement reads
   as an orbit rather than as icons scattered around a logo.

   It is one 1px hairline in --m-orbit and it is derived, not drawn - the same
   --dd-rx/--dd-ry the nodes are placed with, inherited from the stage - so it
   cannot drift out of step with them at any breakpoint. The nodes sit ON it
   and paint over it, and their backdrop-filter softens the arc passing behind
   the glass, which is what gives the discs their thickness. */
.dd-map__wires::before,
.dd-map__wires::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: calc(var(--dd-rx) * 2);
	height: calc(var(--dd-ry) * 2);
	transform: translate(-50%, -50%);
	border-radius: 50%;
}

.dd-map__wires::before {
	border: 1px solid var(--m-orbit);
}

/* The lit arc: the stretch of the path the OPEN node stands on, brightened.

   Same state as the lit wire and the coin's lighting, and driven by the same
   one number - --dd-lit-a, the bearing of the open node, inherited from the
   stage and interpolated by the browser (it is a registered <angle>). So the
   bright stretch travels round the path as the selection moves instead of
   jumping, and it always arrives exactly under the node the console belongs
   to. Decoration that encodes nothing would not be here.

   The +62deg turns a CSS bearing (0 = right, -90 = up) into a conic angle
   (0 = up, clockwise) and then backs off half the arc's width, so the sector
   is centred on the node rather than starting at it. The mask clips the
   element's whole rendering, box-shadow included, so the glow is an arc too.
   Ellipse, not circle: the mask is conic about the same centre, so the sector
   lands on the path however flat the ellipse is at this breakpoint. */
.dd-map__wires::after {
	border: 1px solid var(--m-arc);
	box-shadow: 0 0 12px var(--m-arc-glow);
	-webkit-mask-image: conic-gradient(from calc(var(--dd-lit-a) + 62deg), #000 0deg, #000 56deg, transparent 57deg);
	mask-image: conic-gradient(from calc(var(--dd-lit-a) + 62deg), #000 0deg, #000 56deg, transparent 57deg);
}

/* Anchored at the stage centre, rotated to the node's true bearing on the
   ellipse, then pushed out to clear the core disc. Width spans exactly the gap
   between core edge and node edge. */
/* The breakpoint pair MUST be selected here, on the element that actually
   carries --lm/--ld/--am/--ad. A custom property's var() is substituted on the
   element where it is DECLARED, so hoisting this to .dd-map__stage resolved
   var(--lm) against the stage - where it does not exist - and every wire
   silently computed to width 0. */
.dd-map__wire {
	--dd-wire-l: var(--lp);
	--dd-wire-a: var(--ap);

	position: absolute;
	left: 50%;
	top: 50%;
	height: 1px;
	width: calc(var(--dd-wire-l) * var(--dd-stage) - var(--dd-core-r) - var(--dd-node-r));
	transform-origin: 0 50%;
	transform: rotate(calc(var(--dd-wire-a) * 1deg)) translateX(var(--dd-core-r));
	background: linear-gradient(90deg, transparent, var(--m-wire) 22%, var(--m-wire) 78%, transparent);
	opacity: 0.9;
	transition: opacity 0.28s ease;
}

/* The lit spoke carries a glow of its own now. On black a 1px gold line at
   85% alpha is still only a 1px gold line; the shadow is what makes the
   connection read from across the section. */
.dd-map__wire.is-on {
	background: linear-gradient(90deg, transparent, rgba(253, 184, 55, 0.9) 20%, rgba(253, 184, 55, 0.9) 80%, transparent);
	box-shadow: 0 0 10px rgba(253, 184, 55, 0.45);
	opacity: 1;
}

/* The travelling spark. It carries meaning - it runs only on the wire feeding
   the open panel, so the eye is told which section the console belongs to.
   Pure transform/opacity, so it composites without repainting the wire. */
.dd-map__wire.is-on::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 0;
	width: 5px;
	height: 5px;
	margin-top: -2.5px;
	border-radius: 50%;
	background: var(--dd-gold-bright);
	box-shadow: 0 0 8px 2px rgba(253, 184, 55, 0.6);
	animation: dd-map-spark 2.6s ease-in-out infinite;
}

@keyframes dd-map-spark {
	0%       { transform: translate3d(0, 0, 0); opacity: 0; }
	18%      { opacity: 1; }
	82%      { opacity: 1; }
	100%     { transform: translate3d(calc(var(--dd-wire-l) * var(--dd-stage) - var(--dd-core-r) - var(--dd-node-r) - 5px), 0, 0); opacity: 0; }
}

/* ---------- core --------------------------------------------------------- */

/* The lit bearing: which way the open node lies, as an angle. Everything about
   the coin's transparency is derived from this ONE number, which is why it is
   registered - an unregistered custom property is a string and jumps between
   values, a registered <angle> interpolates, so the light swings round the rim
   instead of teleporting.

   Initial value matches the node PHP ships open (index 0, -90deg = top), so
   the coin is already lit correctly before dd-map.js runs. Browsers without
   @property fall back to the inline value PHP prints on the stage; they get
   the right lighting, just without the sweep. */
@property --dd-lit-a {
	syntax: "<angle>";
	inherits: true;
	initial-value: -90deg;
}

.dd-map__core {
	position: absolute;
	left: 50%;
	top: 50%;
	width: var(--dd-core);
	height: var(--dd-core);
	transform: translate(-50%, -50%);
	border-radius: 50%;
	border: 0;
	/* The mark fills this disc edge to edge and now carries its own hard rim, so
	   the core draws no plate and no ring - the coin defines its own edge and
	   the wires terminate exactly on it.

	   The bloom behind it is deliberately kept OUTSIDE the coin: it starts at
	   the rim (60%) instead of at the centre. The old version began at the
	   centre and laid a pale gold wash across the coin's own lower half, which
	   is half of what made the bottom look washed out. */
	background:
		radial-gradient(closest-side, transparent 58%, rgba(253, 184, 55, 0.16) 78%, transparent 100%);
	box-shadow: 0 10px 34px -20px rgba(150, 112, 0, 0.5);
	display: grid;
	place-items: center;
}

/* ---------- the moving light -------------------------------------------- */

/* The swing. Declared on the STAGE because that is where JS writes the angle,
   and a registered property only transitions on the element whose own value
   changes; the core inherits each interpolated value as it lands, which is what
   carries the light round rather than snapping it.

   .62s is tuned against the longest move on the orbit - the 180deg jump from
   the top node to the bottom one. */
.dd-map__stage {
	transition: --dd-lit-a 0.62s cubic-bezier(0.32, 0.72, 0.28, 1);
}

/* Both of these are driven by --dd-lit-a, the bearing of the open node, and
   both work by ADDING light. That is the design constraint, not a detail: the
   coin's own pixels are never masked or faded, so no state of this effect can
   deform the mark. See the note on .dd-map__logo.

   The lit point is shared, so the halo outside and the sheen inside always
   agree about where the light is coming from. */
.dd-map__core {
	--dd-lit-x: calc(50% + 30% * cos(var(--dd-lit-a)));
	--dd-lit-y: calc(50% + 30% * sin(var(--dd-lit-a)));
}

/* «halo» - a translucent gold pool AROUND the coin, swelling on the side the
   open node is on. Being outside the rim is what makes it safe: it is drawn on
   the page, not on the mark.

   -34% pushes it well clear of the coin, and z-index:-1 drops it behind the
   <img>. The core already has a transform, so it is a stacking context and the
   negative index cannot escape behind the section's own background. */
.dd-map__core::before {
	content: "";
	position: absolute;
	inset: -34%;
	z-index: -1;
	border-radius: 50%;
	pointer-events: none;
	background: radial-gradient(closest-side at var(--dd-lit-x) var(--dd-lit-y),
		rgba(253, 184, 55, 0.44),
		rgba(253, 184, 55, 0.16) 44%,
		rgba(253, 184, 55, 0) 72%);
}

/* «sheen» - the specular pool on the coin's face. Purely additive: a soft warm
   white that brightens the lit side and fades to nothing well before the rim,
   so there is no edge of its own to misalign with the coin's edge and nothing
   anywhere that darkens or thins the mark.

   It sits ABOVE the <img> - positioned, so it paints over an in-flow sibling
   without needing an index of its own. */
.dd-map__core::after {
	content: "";
	position: absolute;
	inset: 4%;
	border-radius: 50%;
	pointer-events: none;
	background: radial-gradient(closest-side at var(--dd-lit-x) var(--dd-lit-y),
		rgba(255, 246, 222, 0.5),
		rgba(255, 240, 200, 0.16) 38%,
		rgba(255, 236, 190, 0) 66%);
}

/* The brand mark IS the disc.
   assets/img/dd-coin-mark.* - built from the site icon, which is the one
   drawing of this coin that is actually CIRCULAR (r is 255.5 in every
   direction). See dd_map_logo() for why the hero watermark cannot be used here.
   It is round, hard-edged, undistorted and fills its square exactly, which is
   what lets everything below be deleted rather than tuned: no scale-up to reach
   the wires, no drop-shadow to fake a lower rim, and no saturate() stack - the
   colour lift is baked into the file now.
   The <picture> wrapper must not become a layout box of its own.
   `!important` on every box property because the theme's content-image rules
   otherwise frame and resize any <img> in this column. */
.dd-map__core picture {
	display: contents;
}
.dd-map .dd-map__logo {
	display: block;
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	aspect-ratio: 1 !important;
	object-fit: contain;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 50% !important;
	box-shadow: none !important;
	background: none !important;
	opacity: 1;

	/* The coin is lit from the top, so its lower rim is the palest thing in the
	   artwork - and on a cream page a pale gold rim against #faf7ef is barely
	   an edge at all. The owner has read that before as the bottom of the logo
	   being cut off. This gives that edge a silhouette to sit on; it adds
	   nothing to the coin's own pixels, which is the standing rule here.
	   Dark mode drops it (below): against black the pale rim IS the separation,
	   and a shadow under it would only muddy the halo. */
	filter: drop-shadow(0 6px 14px rgba(150, 112, 0, 0.22));

	/* NOTHING MAY SUBTRACT FROM THESE PIXELS. No mask, no alpha gradient,
	   no opacity below 1, however directional or well-behaved it looks in
	   isolation.

	   This was tried on 2026-08-14 - a two-layer mask that thinned only the
	   recessed face and pinned the raised rim solid - and it was rejected
	   for the same reason every previous attempt was: the coin is a
	   stylised 3D render, and what makes it read as ROUND is the shading
	   gradient across its rim and face. Take alpha out of any part of that
	   and the eye stops seeing a circle lit from one side and starts seeing
	   a lopsided blob. Pinning the rim does not save it, because the rim is
	   not the only thing carrying the shape.

	   See dd_map_logo() in inc/home-map.php for the full history - an
	   ellipse under the old baked fade, a stretched D$ when it was
	   resampled round, and the owner's verdict on all of it: a deformed
	   glyph is a deformed logo.

	   The interactive lighting this section wants is done ADDITIVELY
	   instead, in the two pseudo-elements on .dd-map__core: a halo outside
	   the rim and a sheen over the face, both driven by --dd-lit-a. Adding
	   light cannot deform a silhouette; removing it always can. */
}

/* ---------- nodes -------------------------------------------------------- */

.dd-map__ring {
	position: absolute;
	inset: 0;
}

/* The polar placement. translate(-50%,-50%) centres the button on its own
   box; the second translate walks it out along the ellipse. */
.dd-map__node {
	position: absolute;
	left: 50%;
	top: 50%;
	width: var(--dd-node);
	height: var(--dd-node);
	transform:
		translate(-50%, -50%)
		translate(calc(var(--dd-rx) * var(--cos)), calc(var(--dd-ry) * var(--sin)));
	margin: 0;
	padding: 0;
	border: 1px solid var(--m-brd);
	border-radius: 50%;
	/* Top-lit glass, not a flat swatch: the fill runs light at the top and
	   thins at the bottom and the 1px inner highlight sits on the upper rim,
	   so the disc has a direction and a thickness. It is the same material as
	   the cards in the console - one section, one substance. */
	background: var(--m-tile);
	box-shadow: var(--m-hi), var(--m-lift);
	color: var(--dd-muted);
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	transition: border-color 0.22s ease, color 0.22s ease, box-shadow 0.26s ease;
}

/* Scale lives on the inner span so it never fights the polar transform on the
   button itself. */
.dd-map__node-in {
	display: grid;
	place-content: center;
	gap: 3px;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	transition: transform 0.26s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.dd-map__i {
	width: calc(var(--dd-stage) * 0.062);
	height: calc(var(--dd-stage) * 0.062);
	margin-inline: auto;
	display: block;
}

.dd-map__node-lb {
	font-size: calc(var(--dd-stage) * 0.0345);
	font-weight: 700;
	line-height: 1.35;
	text-align: center;
	white-space: nowrap;
}

.dd-map__node:hover {
	color: var(--dd-ink);
	border-color: var(--m-brd-lit);
	box-shadow: var(--m-hi), var(--m-lift-up);
}

.dd-map__node:hover .dd-map__node-in {
	transform: scale(1.06);
}

/* The open node. Three things say so and they are all the same statement -
   the disc is gold, it is ringed, and it is the brightest object on the path
   after the coin. The outer ring is a 1px spread shadow rather than a second
   border so it cannot shift the button's geometry on the ellipse. */
.dd-map__node.is-on {
	color: #4a3600;
	border-color: rgba(224, 190, 0, 0.62);
	background: linear-gradient(160deg, rgba(253, 184, 55, 0.4), rgba(224, 190, 0, 0.2));
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.55),
		0 0 0 1px rgba(224, 190, 0, 0.35),
		0 14px 30px -12px rgba(224, 190, 0, 0.8);
}

.dd-map__node.is-on .dd-map__node-in {
	transform: scale(1.08);
}

.dd-map__node:focus-visible {
	outline: 2px solid var(--dd-gold-bright);
	outline-offset: 3px;
}

/* ---------- console ------------------------------------------------------ */

/* The console is the one piece of glass in the section and everything else
   sits on it, so it is lit like glass: a top-lit fill, a 1px inner highlight
   on its upper rim, and a warm pool bleeding in from the side the orbit is
   actually on - above it on a phone, beside it on the right at >=1024, where
   the coin really is. That is why the pool is off-centre and why it moves at
   the breakpoint: the panel is lit BY the constellation. A centred glow would
   be decoration; this one says where the light comes from. */
.dd-map__console {
	position: relative;
	margin: clamp(9px, 2.2vw, 26px) auto 0;
	max-width: 940px;
	padding: clamp(15px, 3.6vw, 24px);
	border: 1px solid var(--m-brd);
	border-radius: var(--dd-radius-lg);
	background:
		radial-gradient(120% 86% at var(--m-spill-at, 50% -14%), var(--m-spill), transparent 60%),
		var(--m-glass);
	box-shadow: var(--dd-shadow), var(--m-hi);
	backdrop-filter: blur(9px);
	-webkit-backdrop-filter: blur(9px);
	/* Holds the tallest panel's height so switching sections never reflows the
	   page below. Tuned to the voucher/contact panels, which are the tallest. */
	min-height: 284px;
}

/* A column so the panel can fill a console that is taller than its content -
   which is exactly what happens once the console matches the orbit's height.
   Without this the content sat at the top and left a dead gap underneath. */
.dd-map__panel {
	display: flex;
	flex-direction: column;
	height: 100%;
	animation: dd-map-in 0.3s ease both;
}

/* (0,2,0) so it beats the display:flex above. */
.dd-map__panel[hidden] {
	display: none;
}

@keyframes dd-map-in {
	from { opacity: 0; transform: translate3d(0, 7px, 0); }
	to   { opacity: 1; transform: none; }
}

/* ---------- panel head --------------------------------------------------- */

/* One console bar: the section's own glyph, its name, and the way further in.
   The glyph is the same one the lit node is wearing, which is what ties the
   open panel to the selected node without drawing anything between them. */
.dd-map__panel-head {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 7px;
}

/* Icon tile - the approved emphasis device. Not a rail, not a pill above a
   heading: it sits BESIDE the title, on the same line. */
.dd-map__panel-ico {
	flex: none;
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	border-radius: 11px;
	background: rgba(224, 190, 0, 0.16);
	color: var(--dd-gold-deep);
}

.dd-map__panel-ico .dd-map__i {
	width: 19px;
	height: 19px;
}

/* Overrides the theme's inline `h2 { display:flex; text-align:center }`. */
/* Two classes (0,2,0) so this beats the theme's `div.text h2` (0,1,2) - both
   carry !important, so the specificity is what decides. A one-class reset was
   measurably losing on text-align and margin. */
.dd-map .dd-map__panel-h {
	flex: 1 1 auto;
	display: block;
	min-width: 0;
	margin: 0 !important;
	padding: 0;
	font-size: clamp(16.5px, 4.2vw, 20px) !important;
	font-weight: 800;
	line-height: 1.5;
	text-align: start !important;
}

.dd-map .dd-map__panel-lead {
	margin: 0 0 11px;
	color: var(--dd-muted);
	font-size: clamp(12px, 3.2vw, 13.5px) !important;
	line-height: 1.85;
}

/* ---------- entity grids ------------------------------------------------- */

.dd-map__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 8px;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	align-content: start;
}

/* Three items never divide into two columns - the odd one out sat alone on a
   second row with a full-width card beside nothing. Stacked, always. */
.dd-map__grid--3 {
	grid-template-columns: minmax(0, 1fr);
}

/* Rows the same height at every width. The <=859 and >=1024 blocks each do
   this inside a pinned console, but the 860-1023 band - where the four coins
   sit in a single row - had no rule at all. Stated once, at the base, so no
   breakpoint can lose it. minmax(0, 1fr), never a bare `1fr`: the bare form
   floors at the row's own content and refuses to shrink. */
.dd-map__grid--4 {
	grid-auto-rows: minmax(0, 1fr);
	align-content: stretch;
}

/* THEME TRAP. The parent theme ships `div.text li { padding-bottom: 8px }` and
   this section renders inside div.text, so every list item here picked up 8px
   of padding under its card - all of them except the last, which a
   `li:last-child` rule elsewhere zeroes.

   The `.dd-map li { padding: 0 }` reset above does NOT hold: it is the same
   (0,1,1) specificity as the theme's rule and loses on source order, which is
   why the list-style beside it is already marked !important. Same fix, same
   reason.

   What it looked like: the rows are equalised, so every li was 175px - but
   three of the four cards were laid out inside 167px of it and only ترون, the
   last coin, filled its row. Three cards 8px short of the fourth, measured in
   Chrome on 2026-08-27. Every panel in the console had it, not just رمزارز. */
.dd-map__grid > li,
.dd-map__posts > li {
	padding: 0 !important;
}

.dd-map__ent {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 4px;
	min-height: 62px;
	height: 100%;
	padding: 10px 12px;
	border: 1px solid var(--m-brd);
	border-radius: var(--dd-radius);
	background: var(--m-tile);
	box-shadow: var(--m-hi), var(--m-lift);
	color: var(--dd-ink);
	text-decoration: none;
	transition: border-color 0.2s ease, transform 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.2), box-shadow 0.22s ease;
}

/* Hover is the only place gold touches a card's edge, and it means one thing:
   this is a link and it is under your cursor. */
.dd-map__ent:hover {
	border-color: var(--m-brd-lit);
	background: var(--m-tile-hover);
	box-shadow: var(--m-hi), var(--m-lift-up);
	transform: translateY(-3px);
}

.dd-map__ent:focus-visible {
	outline: 2px solid var(--dd-gold-bright);
	outline-offset: 2px;
}

.dd-map__ent-top {
	display: flex;
	align-items: center;
	gap: 7px;
}

/* Ticker chip. A tinted tile, not a coloured rail - it identifies the asset. */
.dd-map__sym {
	flex: none;
	padding: 2px 7px;
	border-radius: 7px;
	background: rgba(224, 190, 0, 0.16);
	color: var(--dd-gold-deep);
	font-size: 10.5px;
	font-weight: 800;
	letter-spacing: 0.4px;
	line-height: 1.7;
}

.dd-map__ent-nm {
	font-size: 13.5px;
	font-weight: 700;
	line-height: 1.6;
}

.dd-map__ent-nm--lg {
	font-size: 14.5px;
}

/* 24h move. Read from the cache [dd_coin_table] further down the page already
   fills, so it costs no request - see dd_map_changes(). It rides the top line
   beside the ticker rather than the price line: بیت کوین's Toman figure is 14
   glyphs wide and the two together overran a half-width card.
   Direction colour, not decoration - the same green/red the coin boxes use. */
.dd-map__chg {
	margin-inline-start: auto;
	flex: none;
	padding: 2px 6px;
	border-radius: 7px;
	font-size: 10.5px;
	font-weight: 800;
	line-height: 1.7;
	font-variant-numeric: tabular-nums;
}

.dd-map__chg--up { background: rgba(30, 169, 124, 0.14); color: var(--dd-up); }
.dd-map__chg--dn { background: rgba(226, 85, 78, 0.14); color: var(--dd-down); }

/* The same day read twice - «ت» is the move for someone paying in Toman, «$»
   the move in the world market. They stack rather than sitting side by side:
   the top line's horizontal budget is already spent (see the note above), and
   stacking keeps the widest chip governing the width instead of their sum. */
.dd-map__chgpair {
	margin-inline-start: auto;
	flex: none;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 2px;
}

.dd-map__chgpair .dd-map__chg { margin-inline-start: 0; }

.dd-map__chg i {
	font-style: normal;          /* Persian must never be fake-slanted */
	font-weight: 700;
	opacity: 0.6;
	margin-inline-start: 3px;
}

/* the dollar reading: same colour vocabulary, no fill - a footnote, not a peer */
.dd-map__chg--sub {
	padding: 0 6px;
	font-size: 9.5px;
	opacity: 0.9;
}

.dd-map__chg--sub.dd-map__chg--up,
.dd-map__chg--sub.dd-map__chg--dn { background: transparent; }

.dd-map__ent-note {
	color: var(--dd-muted);
	font-size: 11.5px;
	line-height: 1.7;
}

/* ---------- contact rows ------------------------------------------------- */

/* Horizontal variant: icon tile beside the text instead of a stack. The three
   channels were previously two bare lines of text each, which named the
   channel without showing anything - these carry the real number, the real
   handle and the real street. */
.dd-map__ent--row {
	flex-direction: row;
	align-items: center;
	/* .dd-map__ent centres its children for the stacked variant; in a row that
	   left the icon and text floating in the middle of the card with dead
	   space on both sides. These start at the reading edge. */
	justify-content: flex-start;
	gap: 13px;
}

.dd-map__ent--row .dd-map__ent-go {
	display: grid;
}

.dd-map__ent-body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

/* Closes the row at the far edge - see the note on the markup. margin-auto
   rather than space-between so the icon and the text stay glued together.
   `display: none` is the default because the voucher tiles ship one too and it
   only earns its place once they turn into rows at >=1024. */
.dd-map__ent-go {
	display: none;
	flex: none;
	margin-inline-start: auto;
	place-items: center;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	background: rgba(224, 190, 0, 0.1);
	color: var(--dd-gold-deep);
	transition: transform 0.22s ease, background-color 0.22s ease;
}

/* -3px, not +3: transform is not mirrored by `dir`, and this chevron sits at
   the RTL end (the left) pointing left. Moving it right would walk it back into
   the text. */
.dd-map__ent--row:hover .dd-map__ent-go {
	background: rgba(224, 190, 0, 0.2);
	transform: translateX(-3px);
}

/* The icon tile - a rounded square with a tinted ground and a gold glyph.
   This is the approved emphasis device; there is no rail or coloured border
   anywhere on the row. */
.dd-map__ico {
	flex: none;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border-radius: 13px;
	background: rgba(224, 190, 0, 0.18);
	color: var(--dd-gold-deep);
}

.dd-map__ico .dd-map__i {
	width: 21px;
	height: 21px;
}

.dd-map__ent-lb {
	color: var(--dd-muted);
	font-size: 11px;
	line-height: 1.6;
}

.dd-map__ent--row .dd-map__ent-nm {
	font-size: 14.5px;
	font-weight: 800;
	letter-spacing: 0.2px;
}

.dd-map__price {
	display: flex;
	align-items: baseline;
	gap: 4px;
}

.dd-map__price-v {
	font-size: 15px;
	font-weight: 800;
	line-height: 1.55;
	font-variant-numeric: tabular-nums;
}

.dd-map__price-u {
	color: var(--dd-muted);
	font-size: 11px;
}

/* Value-flash when a poll moves the number - the same cue the coin boxes use. */
.dd-map__price-v.is-up   { animation: dd-map-flash-up 0.9s ease; }
.dd-map__price-v.is-down { animation: dd-map-flash-dn 0.9s ease; }

@keyframes dd-map-flash-up {
	0%, 100% { color: inherit; }
	22%      { color: var(--dd-up); }
}

@keyframes dd-map-flash-dn {
	0%, 100% { color: inherit; }
	22%      { color: var(--dd-down); }
}

/* ---------- card trend line ---------------------------------------------- */

/* Hidden below 1024 and that is the whole design of it: on a phone the console
   is a fixed 300px divided between four cards, so there is no air to fill and
   a 38px chart would be taking the price's room. It appears only in the wide
   layout, where the card is ~150px tall and the alternative is dead space.

   The svg is the coin table's own (ddcb_table_spark_svg), so the two price
   boards on this page draw a trend the same way rather than each inventing
   one. The sizing is restated here instead of inherited from table.css - this
   section must not silently depend on another shortcode being on the page. */
.dd-map__trend {
	display: none;
	align-items: center;
	gap: 9px;
	/* Puts the chart on the floor of the card: identity, then price, then the
	   line under both. The card's own `justify-content: center` yields to an
	   auto margin, which is what makes this a floor and not a third row. */
	margin-top: auto;
	color: var(--dd-muted);
}

/* Direction is the colour, and it is the same green and red the change chip
   above it uses - one reading, stated twice, never contradicting itself. */
.dd-map__trend[data-trend="up"]   { color: var(--dd-up); }
.dd-map__trend[data-trend="down"] { color: var(--dd-down); }

/* Which period the line covers. It is here because the four cards do NOT share
   an axis - three are a year of readings, تتر is the last 24 hours in Toman -
   and four unlabelled charts side by side would imply they do. */
.dd-map__trend-k {
	flex: none;
	color: var(--dd-muted);
	font-size: 10.5px;
	line-height: 1.7;
	letter-spacing: 0.2px;
}

.dd-map__spark {
	flex: 1 1 auto;
	min-width: 0;
	display: block;
}

.dd-map__spark .ddt-spark {
	position: relative;
	display: block;
	width: 100%;
}

.dd-map__spark .ddt-spark__svg {
	display: block;
	width: 100%;
	height: 38px;
	overflow: visible;
}

/* The table's version knocks the dot out of the card with a 3px ring in
   --dd-card; that token is translucent, so on this section's glass it prints
   as a smudge. A plain glow reads cleaner and needs no knowledge of what is
   behind it. */
.dd-map__spark .ddt-spark__end {
	width: 6px;
	height: 6px;
	box-shadow: 0 0 9px 1px currentColor;
}

/* ---------- voucher rate line -------------------------------------------- */

.dd-map__rate {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 4px 6px;
	margin-bottom: 9px;
	padding: 9px 13px;
	border: 1px solid var(--m-brd-lit);
	border-radius: var(--dd-radius);
	background: linear-gradient(180deg, rgba(253, 184, 55, 0.15), rgba(253, 184, 55, 0.05));
	box-shadow: var(--m-hi);
}

.dd-map__rate-lb {
	color: var(--dd-muted);
	font-size: 12.5px;
}

.dd-map__rate-v {
	display: flex;
	align-items: baseline;
	gap: 4px;
}

.dd-map__rate-v .dd-map__price-v {
	font-size: 18px;
}

/* ---------- gift card art ------------------------------------------------ */

/* Stacked by default - face on top, name and note beneath. At >=1024, where the
   console becomes a narrow column, these turn into rows exactly as the vouchers
   do; that rule lives with the rest of that layout at the foot of this file. */
.dd-map__ent--art {
	align-items: stretch;
	text-align: center;
	gap: 9px;
	min-height: 96px;
}

/* The card object.
   Not a swatch with a logo dropped on it. A real gift card has a chip, a lit
   top edge and a mark printed at logo size, and this is the same primitive the
   /giftcard/ hub is built from - drawn at the size this console can pay for.
   What was here before filled 46% of a 1.9:1 banner with the brand mark: the
   shape said nothing, the mark said the card's name a second time, and four of
   them together read as a wall of placeholders.
   1.586 is ID-1, the ratio a gift card actually is.
   --f/--t come from the dd_giftcards registry, so recolouring a card there
   recolours it here. */
.dd-map__face {
	position: relative;
	display: block;
	overflow: hidden;
	flex: none;
	width: 100%;
	aspect-ratio: 1.586;
	border-radius: 12px;
	background: linear-gradient(148deg, var(--f, #2a2a30) 0%, var(--t, #4a4a55) 62%, var(--f, #2a2a30) 130%);
	box-shadow:
		0 1px 0 rgba(255, 255, 255, 0.28) inset,
		0 -12px 22px -16px rgba(0, 0, 0, 0.8) inset,
		0 8px 20px -10px rgba(20, 20, 35, 0.55);
}

/* The engraved ground and the corner bloom, in one element. Both are white at
   low alpha over the brand colour, so every card keeps its own identity instead
   of wearing a house texture. */
.dd-map__face-fx {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image:
		repeating-linear-gradient(112deg, rgba(255, 255, 255, 0.055) 0 1px, transparent 1px 8px),
		radial-gradient(120% 130% at 8% -18%, rgba(255, 255, 255, 0.3), transparent 58%);
	mix-blend-mode: screen;
}

/* The chip - the one detail that makes a coloured rectangle read as a card, and
   the reason it survives at this size when the hub's guilloche and sheen do not.

   A chip is a physical gold object and has no dark mode, hence literal hexes
   rather than tokens - and hence the four pins below. The dark mode plugin
   rewrites every literal colour in a stylesheet into
   `var(--dracula-background-<hex>, <dark fallback>)`, which turned this gradient
   into four shades of mud (#f6e2a4 came back as #4f4528). Declaring the
   variables the plugin's own rule reads, on the element that uses them, is what
   holds - see DESIGN-BANS trap #7. Verified in the browser, not in the CSS:
   every earlier fix looked correct in the stylesheet and failed on the page. */
.dd-map__face-chip {
	--dracula-background-f6e2a4: #f6e2a4;
	--dracula-background-cfa94b: #cfa94b;
	--dracula-background-f4e6b6: #f4e6b6;
	--dracula-background-b8912f: #b8912f;
	position: absolute;
	inset-inline-end: 9%;
	inset-block-start: 15%;
	width: 12.5%;
	aspect-ratio: 1.28;
	border-radius: 2px;
	background: linear-gradient(150deg, #f6e2a4 0%, #cfa94b 42%, #f4e6b6 60%, #b8912f 100%);
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
	opacity: 0.92;
}

/* The theme's content-image rules put a gold frame and their own sizing on any
   <img> in this column; all three axes are pinned back here. Centred on the
   face and capped by height, the way the hub prints it - a logo on a card, not
   a sticker over it. */
.dd-map .dd-map__art {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -52%);
	width: 32% !important;
	height: auto !important;
	max-width: none !important;
	max-height: 44%;
	aspect-ratio: 1 !important;
	object-fit: contain;
	display: block;
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	background: none !important;
	filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.42));
}

/* ---------- blog rows ---------------------------------------------------- */

.dd-map__posts {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 8px;
	align-content: start;
}

.dd-map__post {
	display: flex;
	align-items: center;
	/* Fills the grid row the way .dd-map__ent does. Without it the card stayed
	   content-sized inside a stretched row and the blog panel rendered as three
	   pairs of cards floating over three bands of empty console. */
	height: 100%;
	gap: 9px;
	padding: 11px 12px;
	border: 1px solid var(--m-brd);
	border-radius: var(--dd-radius);
	background: var(--m-tile);
	box-shadow: var(--m-hi), var(--m-lift);
	color: var(--dd-ink);
	text-decoration: none;
	transition: border-color 0.2s ease, transform 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.2), box-shadow 0.22s ease;
}

.dd-map__post:hover {
	border-color: var(--m-brd-lit);
	background: var(--m-tile-hover);
	box-shadow: var(--m-hi), var(--m-lift-up);
	transform: translateY(-3px);
}

/* Kind badge. These are the three content kinds the site already colour-codes
   (gold مقاله / red خبر / blue تحلیل), so the colour carries real meaning. */
.dd-map__kind {
	flex: none;
	padding: 3px 9px;
	border-radius: 8px;
	font-size: 11px;
	font-weight: 700;
	line-height: 1.7;
}

.dd-map__kind--article  { background: rgba(224, 190, 0, 0.18); color: var(--dd-gold-deep); }
.dd-map__kind--news     { background: rgba(226, 85, 78, 0.15); color: #b23c36; }
.dd-map__kind--analysis { background: rgba(56, 118, 214, 0.15); color: #2f63b0; }

.dd-map__post-t {
	font-size: 13px;
	font-weight: 600;
	line-height: 1.75;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.dd-map__empty {
	margin: 0;
	color: var(--dd-muted);
	font-size: 13px;
}

/* ---------- panel: what the account actually is -------------------------- */

/* Rows, not cards: these are three facts to read in order, and a hairline
   between them is enough separation. No tile, no border - the icon discs carry
   the rhythm and the panel stays quieter than the two buttons under it, which
   is the point. */
.dd-map__perks {
	list-style: none;
	margin: 0 0 11px;
	padding: 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 2px;
}

.dd-map__perks li {
	display: flex;
	align-items: center;
	gap: 11px;
	padding: 8px 2px;
	border-bottom: 1px solid var(--dd-card-brd);
}

.dd-map__perks li:last-child {
	border-bottom: 0;
}

.dd-map__perks .dd-map__ent-nm {
	font-size: 13.5px;
	font-weight: 700;
}

/* ---------- panel CTA ---------------------------------------------------- */

.dd-map__panel-cta {
	display: grid;
	gap: 10px;
	grid-template-columns: minmax(0, 1fr);
}

.dd-map__go,
.dd-map__ghost {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	min-height: 62px;
	padding: 11px 18px;
	border-radius: 15px;
	text-decoration: none;
	overflow: hidden;
	transition: transform 0.2s ease, box-shadow 0.25s ease;
}

.dd-map__go {
	background: var(--dd-grad);
	color: #3d2c00;
	border: 1px solid rgba(224, 190, 0, 0.55);
	box-shadow: 0 14px 32px -16px rgba(224, 190, 0, 0.9);
}

.dd-map__ghost {
	background: var(--dd-tile);
	color: var(--dd-ink);
	border: 1px solid var(--dd-card-brd);
}

.dd-map__go:hover,
.dd-map__ghost:hover {
	transform: translateY(-2px);
}

.dd-map__ghost:hover {
	border-color: var(--dd-hair);
}

.dd-map__go-tx {
	position: relative;
	font-size: 15px;
	font-weight: 800;
	line-height: 1.6;
}

.dd-map__go-sub {
	position: relative;
	font-size: 11.5px;
	opacity: 0.78;
	line-height: 1.6;
}

/* Sheen sweep on the primary CTA. transform-only, so it composites. */
.dd-map__go-sheen {
	position: absolute;
	top: 0;
	bottom: 0;
	width: 46%;
	left: -60%;
	background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.55), transparent);
	animation: dd-map-sheen 4.6s ease-in-out infinite;
	pointer-events: none;
}

@keyframes dd-map-sheen {
	0%, 62% { transform: translate3d(0, 0, 0); }
	100%    { transform: translate3d(340%, 0, 0); }
}

/* ---------- «more» link -------------------------------------------------- */

/* Lives in the head row, not at the foot of the panel: it saves the ~43px that
   decides whether the console clears the fold on a phone, and it reads as the
   console's own «go there» control rather than an afterthought. */
.dd-map__more {
	flex: none;
	display: inline-flex;
	align-items: center;
	gap: 4px;
	margin: 0;
	padding: 6px 10px 6px 8px;
	border-radius: 10px;
	background: rgba(224, 190, 0, 0.1);
	color: var(--dd-gold-deep);
	font-size: 11.5px;
	font-weight: 700;
	line-height: 1.5;
	white-space: nowrap;
	text-decoration: none;
	transition: gap 0.2s ease, background-color 0.2s ease;
}

.dd-map__more:hover {
	gap: 8px;
	background: rgba(224, 190, 0, 0.18);
}

.dd-map__more svg {
	flex: none;
}

/* Below 400px the longest hub label («قیمت ووچر و همه انواع آن») and the title
   together overrun the row, so the chip drops to its own line rather than
   squeezing the title to an ellipsis. */
@media (max-width: 399px) {
	.dd-map__panel-head {
		flex-wrap: wrap;
		row-gap: 7px;
	}

	.dd-map__more {
		font-size: 11px;
		padding: 5px 9px 5px 7px;
	}

	/* Under 400px the پنل lead reliably takes a third line and its three perk
	   rows no longer fit above the buttons. Dropping the last one is a better
	   failure than clipping it: the two that stay answer «what will this cost
	   me», and the گام به گام chip in the head goes to the full version. */
	.dd-map__perks li:nth-child(3) {
		display: none;
	}
}

/* ---------- trust line --------------------------------------------------- */

.dd-map__trust {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 10px 18px;
	max-width: 940px;
	margin: clamp(14px, 2vw, 20px) auto 0;
	padding-top: clamp(13px, 2vw, 18px);
	/* A hairline separating the credentials from the console - the approved
	   emphasis device, deliberately not a coloured rail. */
	border-top: 1px solid var(--m-brd);
}

.dd-map__creds {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px 16px;
}

.dd-map__creds li {
	display: flex;
	align-items: center;
	gap: 6px;
	color: var(--dd-muted);
	font-size: 12px;
	line-height: 1.7;
}

.dd-map__creds .dd-map__i {
	width: 15px;
	height: 15px;
	color: var(--dd-gold-deep);
	flex: none;
}

.dd-map__creds-link {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	color: var(--dd-gold-deep);
	font-size: 12.5px;
	font-weight: 700;
	text-decoration: none;
}

.dd-map__creds-link:hover {
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* ===========================================================================
 * Phone - the console has to finish on the same screen as the orbit.
 *
 * Everything in this block is bought with the same currency: vertical space.
 * The section opens the page, the visitor's first move is to tap a node, and
 * the answer to that tap has to be visible without scrolling - otherwise the
 * orbit is a menu whose menu items are off-screen.
 *
 * Budget on a 390x750 phone, measured: orbit ends at ~437, console runs
 * ~450-730. The trust row falls below the fold on purpose - it is a credential
 * strip, not an answer.
 * ======================================================================== */

@media (max-width: 859px) {

	/* ONE height for all six panels, exactly as the >=1024 layout does it.
	   Letting it size to its content instead meant تماس was 51px taller than
	   رمزارز, so every tap nudged the whole page - and the panel a visitor was
	   reading moved under their thumb. Fixed and equal, the orbit above it
	   never moves and the fold never changes.

	   300px is the CONTENT's number and it does not move. Every row of a panel
	   divides whatever the console is given, and a grid child can be squeezed
	   to nothing but can never be made to render its text smaller - so a
	   shorter console does not shrink the content, it makes it escape. Tried
	   on 2026-08-21 and reported from a real 390px phone: at ~250px the
	   voucher tiles printed their notes outside their own boxes, the blog
	   titles ran past the card edge, and پنل's perks overlapped the lead.

	   The fold is made to fit by shrinking the ORBIT instead - see the
	   @supports block further down. That is the right way round: the orbit is
	   a picture and loses nothing at 90% of its size, the console is six
	   panels of words and loses everything. */
	.dd-map__console {
		height: 300px;
		min-height: 0;
		padding: 13px 13px 15px;
	}

	/* The guarantee behind the fixed height. Every panel below divides the space
	   it is given, but a flex or grid child can only be shrunk to zero - it can
	   never be made to render its own text smaller, so on a narrow phone (where
	   the lead wraps to a second line and takes another 22px) the last row of a
	   panel printed straight through the buttons underneath it. Clipping is not
	   a nice failure, but it is a survivable one, and the rules below are sized
	   so it does not happen above 400px. */
	.dd-map__panel {
		overflow: hidden;
	}

	/* And the same guarantee one level down, per card. The panel's clip stops
	   content escaping the CONSOLE; it does nothing about a card whose row has
	   been divided smaller than the words inside it, which paints its note or
	   its title straight through its own bottom border and onto the card below.
	   That is what a real phone showed on the voucher and blog panels.
	   With the 290px floor above this should never fire - it is the guard, not
	   the fix, and clipping a descender is a survivable failure where text
	   floating outside a box is not. */
	.dd-map__ent,
	.dd-map__post {
		overflow: hidden;
	}

	/* The body absorbs whatever the head leaves and divides it between its rows,
	   so a four-row panel and a two-row panel both end at the same line. */
	.dd-map__grid--4,
	.dd-map__grid--3,
	.dd-map__posts {
		flex: 1;
		align-content: stretch;
		/* minmax(0, 1fr), NOT 1fr. A bare `1fr` track is minmax(AUTO, 1fr): the
		   auto floor is the row's content, so the rows refuse to shrink and the
		   panel spills past the console instead of dividing what it has. ووچر
		   overran by 32px on exactly this. */
		grid-auto-rows: minmax(0, 1fr);
		/* Same trap one level out: `flex: 1` cannot shrink a flex item below its
		   content while min-height is auto. */
		min-height: 0;
	}

	/* Exceptions, because stretching these is wrong rather than tight: a
	   gift-card face stretched to 190px is a colour swatch with a logo lost in
	   it, and a 190px-tall CTA is a wall. Content-sized. */
	.dd-map__grid--art {
		flex: 1;
		align-content: center;
		grid-auto-rows: min-content;
		min-height: 0;
	}

	.dd-map__panel-cta {
		flex: none;
	}

	.dd-map__perks {
		flex: 1;
		min-height: 0;
		margin-bottom: 9px;
	}

	.dd-map__perks li {
		gap: 9px;
		padding: 2px;
	}

	/* Two panels land 2-3px over their row at 390px: the blog title's second
	   line and the contact row's third. The card's own padding is the cheapest
	   place to find it - the rows keep their type size and their tap target,
	   and stop clipping a descender. Measured in a 390x674 frame. */
	.dd-map__post {
		padding: 8px 11px;
	}

	.dd-map__ent--row {
		padding: 8px 11px;
		gap: 11px;
	}

	/* The last 3px are in the leading, not the padding: a two-line blog title
	   at 1.75 and a three-line contact row at 1.7 are each a few px over their
	   share of the console. Persian sits fine at 1.6 - it is still looser than
	   the 1.5 the type wants - and it is the difference between a clipped
	   descender and none. */
	.dd-map__post-t {
		line-height: 1.6;
	}

	.dd-map__ent--row .dd-map__ent-note,
	.dd-map__ent--row .dd-map__ent-lb {
		line-height: 1.55;
	}

	/* Titles only. With their notes the three rows wanted 132px of the 101px
	   left after the buttons, and the third one printed straight through them.
	   The three titles on their own still say what the account is - and unlike
	   the notes they cannot wrap on a narrow phone and blow the budget again.
	   The notes are back from 860px up. */
	.dd-map__perks .dd-map__ent-note {
		display: none;
	}

	.dd-map__perks .dd-map__ent-nm {
		font-size: 12.5px;
		line-height: 1.5;
	}

	.dd-map__perks .dd-map__ico {
		width: 28px;
		height: 28px;
		border-radius: 9px;
	}

	.dd-map__perks .dd-map__ico .dd-map__i {
		width: 15px;
		height: 15px;
	}

	/* The floor that stops the rows dividing the space. */
	.dd-map__ent,
	.dd-map__post {
		min-height: 0;
	}

	/* The voucher panel is the tight one: it pays for the rate line out of the
	   same 194px the others spend entirely on cards. */
	.dd-map__rate {
		padding: 7px 11px;
		margin-bottom: 8px;
	}

	.dd-map__rate .dd-map__price-v {
		font-size: 16px;
	}

	.dd-map__rate-lb {
		font-size: 11.5px;
	}

	.dd-map__ent--vch {
		padding: 8px 10px;
		gap: 2px;
	}

	.dd-map__ent-nm--lg {
		font-size: 13.5px;
	}

	.dd-map__ent-note {
		font-size: 11px;
		line-height: 1.6;
	}

	/* Gift cards go from a 2x2 of large faces to a single strip of four
	   (~87px). At a quarter of the console's width the face is still the most
	   recognisable thing in the panel - a brand mark on its own colour survives
	   being small in a way that text does not. */
	.dd-map__grid--art {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 7px;
	}

	/* The face IS the tile here, so the tile around it goes. In a 75px column
	   the card's own padding, border and ground were eating 17px - a quarter of
	   the width - and spending it on a rounded rectangle drawn behind a rounded
	   rectangle. Without it the face is 75px instead of 58 and the brand mark
	   grows with it, which is the whole reason four cards are shown at this size
	   rather than a list of four names. The lift on tap survives; there is
	   nothing left for the border and ground to do. */
	.dd-map__ent--art {
		min-height: 0;
		padding: 0;
		gap: 5px;
		border: 0;
		background: none;
		box-shadow: none;
	}

	.dd-map__ent--art:hover {
		background: none;
		box-shadow: none;
	}

	.dd-map__ent--art .dd-map__ent-nm {
		font-size: 11px;
		line-height: 1.5;
	}

	/* The amounts stay, the regions go. «۵ تا ۱۰۰ دلاری» is one line in an 87px
	   column and it is the half a buyer checks first; the region clause wraps to
	   three lines at this width and costs more height than the card above it.
	   The contact rows drop their third line here for the same reason. */
	.dd-map__ent--art .dd-map__ent-note {
		font-size: 10.5px;
		line-height: 1.5;
	}

	.dd-map__rgn {
		display: none;
	}

	/* A small face needs a proportionally larger mark or the card reads as an
	   empty swatch - which is exactly what the panel looked like before this
	   rebuild, and it does not stop being true because the swatch got smaller. */
	.dd-map .dd-map__art {
		width: 46% !important;
		max-height: 66%;
	}

	.dd-map__face-chip {
		border-radius: 1.5px;
	}

	.dd-map__face {
		min-height: 0;
		border-radius: 9px;
	}

	/* Six posts is a desktop luxury - at this width it is 570px of panel. The
	   remaining three stay in the DOM and stay crawlable; the head's «همه
	   نوشته ها» chip is the way to them. */
	.dd-map__posts li:nth-child(n+4) {
		display: none;
	}

	.dd-map__post {
		padding: 8px 11px;
		gap: 8px;
		align-items: center;
	}

	.dd-map__post-t {
		font-size: 12.5px;
		line-height: 1.6;
	}

	.dd-map__ico {
		width: 34px;
		height: 34px;
		border-radius: 11px;
	}

	.dd-map__ico .dd-map__i {
		width: 18px;
		height: 18px;
	}

	.dd-map__ent--row {
		gap: 10px;
		padding: 8px 10px;
		min-height: 0;
	}

	.dd-map__ent-lb {
		font-size: 10.5px;
		line-height: 1.5;
	}

	.dd-map__ent-go {
		width: 26px;
		height: 26px;
	}

	.dd-map__ent-go svg {
		width: 14px;
		height: 14px;
	}

	.dd-map__ent--row .dd-map__ent-nm {
		font-size: 13.5px;
		line-height: 1.5;
	}

	/* The channel's third line goes on a phone. «تماس تلفنی» + the number is
	   already the whole message; «همه روزه، پاسخ انسانی» is the reassurance, and
	   at three rows it was costing 70px - which is a quarter of the console. It
	   comes back from 860px up, where the height is free. */
	.dd-map__ent--row .dd-map__ent-note {
		display: none;
	}

	.dd-map__panel-head {
		margin-bottom: 6px;
	}

	.dd-map__panel-ico {
		width: 32px;
		height: 32px;
		border-radius: 10px;
	}

	.dd-map__panel-ico .dd-map__i {
		width: 18px;
		height: 18px;
	}

	.dd-map .dd-map__panel-lead {
		margin-bottom: 9px;
	}

	/* A half-width card at this size has ~140px of line to spend, and the coin
	   row wants three things on it: ticker, Persian name, 24h move. «بیت کوین»
	   wrapped to two lines at the shipped sizes, which broke the card's rhythm
	   against its three neighbours - so the whole line is a size down and the
	   name is pinned to one line. */
	.dd-map__ent--coin {
		padding: 10px;
	}

	.dd-map__ent--coin .dd-map__ent-top {
		gap: 5px;
	}

	.dd-map__ent--coin .dd-map__ent-nm {
		font-size: 12.5px;
		white-space: nowrap;
	}

	.dd-map__ent--coin .dd-map__sym {
		font-size: 9.5px;
		padding: 2px 5px;
		letter-spacing: 0.2px;
	}

	.dd-map__chg {
		font-size: 9.5px;
		padding: 2px 5px;
	}

	.dd-map__price-v {
		font-size: 14px;
	}

	.dd-map__panel-cta {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	/* 68 is the buttons' own content height (two lines plus padding), so this is
	   the floor rather than a size - every px above it came out of the perks
	   list above, which is what was overflowing. */
	.dd-map__go,
	.dd-map__ghost {
		min-height: 68px;
		padding: 11px 10px;
	}

	.dd-map__go-tx {
		font-size: 14px;
	}
}

/* Hide the floating «ثبت نام و ورود» pill on the front page at phone widths.
   Owner's call, 2026-08-13, and it is the right one HERE specifically: this
   section's whole job is the six nodes and the console under them, and the
   pill parks itself across the bottom of exactly that. Every other page keeps
   it, and so does the desktop front page - the header's own auth buttons and
   the پنل node cover the same intent on this screen. */
@media (max-width: 767px) {
	html body.home .dd-panel-fab {
		display: none !important;
	}
}

/* ---------------------------------------------------------------------------
 * The fold, made to fit by the orbit.
 *
 * The brief is that a visitor sees the whole constellation AND the console it
 * answers with, without scrolling. Everything above the console is fixed
 * except the orbit, so the orbit is what gives: this shrinks --dd-stage to
 * whatever is left after the page offset, the 88px of header clearance, the
 * gap and the console's 300px - 415px in total, with ~18px of slack in it.
 *
 * Floored at 300px, because below that the node labels stop being readable
 * (they are 0.0345 of the stage) and a phone that short is better served by
 * scrolling a little than by an orbit nobody can read. Never wider than the
 * viewport allows, which is why the vw term is on the outside.
 *
 * `svh` is the SMALL viewport height - the short measurement, with the address
 * bar showing. `vh` is the tall one and would put the console back under the
 * fold on the very first screen, which is the only screen this exists for.
 *
 * Wrapped in @supports because --dd-stage is a custom property: an unsupported
 * unit inside one is not caught at parse time the way it is in a normal
 * declaration, so a browser without svh would not fall back to the line above
 * it - it would resolve to nothing when the width consumes it and the orbit
 * would collapse.
 * ------------------------------------------------------------------------ */

@supports (height: 1svh) {
	@media (max-width: 859px) {
		.dd-map__inner {
			--dd-stage: min(calc(100vw - 34px), max(300px, min(330px, calc((100svh - 415px) / 0.865))));
		}
	}
}

/* ===========================================================================
 * Desktop - the orbit opens out into its landscape ellipse.
 * The ONLY changes are the stage ratios, the wire variable pair, and the
 * console/grid column counts. No second layout exists.
 * ======================================================================== */

@media (min-width: 860px) {

	.dd-map__inner {
		--dd-stage: min(940px, calc(100vw - 90px));
	}

	.dd-map__stage {
		--dd-rx: calc(var(--dd-stage) * 0.410);
		--dd-ry: calc(var(--dd-stage) * 0.232);
		--dd-node: calc(var(--dd-stage) * 0.145);
		--dd-core: calc(var(--dd-stage) * 0.245);

		height: calc(var(--dd-stage) * 0.62);
	}

	/* Swap to the landscape ellipse's bearings - see the note on .dd-map__wire
	   for why this cannot live on the stage. */
	.dd-map__wire {
		--dd-wire-l: var(--ld);
		--dd-wire-a: var(--ad);
	}

	.dd-map__i {
		width: calc(var(--dd-stage) * 0.036);
		height: calc(var(--dd-stage) * 0.036);
	}

	.dd-map__node-lb {
		font-size: calc(var(--dd-stage) * 0.0175);
	}

	.dd-map__grid--3 {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.dd-map__grid--4 {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.dd-map__panel-cta {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.dd-map__console {
		min-height: 250px;
		padding: 24px 26px;
	}

	.dd-map__creds .dd-map__i {
		width: 16px;
		height: 16px;
	}

	.dd-map__creds li {
		font-size: 12.5px;
	}
}

/* ===========================================================================
 * Wide screens - the orbit moves beside the console instead of above it.
 *
 * Stacked, the desktop orbit pushed the console to ~880px down the page, which
 * put the entire point of the section below the fold on a 1440x900 screen
 * (measured). Side by side, the whole orbit and the open panel fit on the
 * first screen together.
 *
 * In RTL the FIRST column named in grid-template-columns is the right-hand
 * one, so listing "stage console" puts the orbit on the right and the console
 * on its left. The two share one grid row, and `align-items: stretch` is what
 * makes the console exactly as tall as the orbit - the console has no height
 * of its own, it inherits the row height the stage sets.
 * ======================================================================== */

@media (min-width: 1024px) {

	.dd-map__inner {
		/* Half-width column, so the orbit shrinks - and because the console
		   reads --dd-stage from here too, it follows automatically. */
		--dd-stage: min(560px, calc(50vw - 60px));

		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 0.98fr);
		grid-template-areas:
			"stage console"
			"trust trust";
		align-items: stretch;
		gap: 4px clamp(24px, 3vw, 48px);
	}

	/* Both columns are pinned to the SAME explicit height - the orbit's natural
	   size, 2*(ry + node radius) with a little air.
	   Letting the row size itself to content was the obvious approach and it
	   is wrong: تماس needs 544px where the other five need 521, so opening it
	   grew the whole section by 23px and everything below it jumped. Fixed and
	   equal means no panel can move the page. The rows inside are 1fr, so a
	   taller panel's content compresses to fit instead.
	   The orbit is absolutely positioned against its own box, so this height
	   only re-centres it - the polar geometry is driven by --dd-stage (a
	   width), never by this. */
	.dd-map__stage {
		grid-area: stage;
		height: calc(var(--dd-stage) * 0.93);
	}

	.dd-map__trust { grid-area: trust; }

	/* The orbit moves out of the console's sky and onto its right-hand side,
	   so both light sources follow it: the ground's pool to where the coin now
	   sits, and the console's spill to the edge nearest it. */
	section.dd-map {
		/* Measured, not estimated: the core's centre sits at 71.0% / 48.9% of
		   the section box in this layout. */
		--m-lamp: 71% 49%;
	}

	.dd-map__console {
		--m-spill-at: 104% 14%;
	}

	.dd-map__console {
		grid-area: console;
		margin: 0;
		/* The same expression as the orbit above - this is the "same height as
		   the constellation" rule. Both derive from --dd-stage, so changing
		   the orbit's size moves them together. */
		height: calc(var(--dd-stage) * 0.93);
	}

	/* A squarer ellipse: the column is no longer page-wide, so the landscape
	   proportions above would flatten the orbit into a line.
	   These rx/ry ratios are EXACTLY the mobile pair (0.377 / 0.360) on
	   purpose - --lm and --am were computed against them in PHP, so reusing
	   the ratios lets this layout reuse the bearings. Change one without the
	   other and every wire ends up pointing slightly off its node. */
	.dd-map__stage {
		--dd-rx: calc(var(--dd-stage) * 0.377);
		--dd-ry: calc(var(--dd-stage) * 0.360);
		--dd-node: calc(var(--dd-stage) * 0.200);
		--dd-core: calc(var(--dd-stage) * 0.305);
		/* No `height` here on purpose - the stretch rule above owns it, and an
		   explicit height in this later block would silently win the cascade
		   and stop the two columns from matching. The floor lives there as
		   min-height. */
	}

	.dd-map__wire {
		--dd-wire-l: var(--lm);
		--dd-wire-a: var(--am);
	}

	.dd-map__i {
		width: calc(var(--dd-stage) * 0.050);
		height: calc(var(--dd-stage) * 0.050);
	}

	.dd-map__node-lb {
		font-size: calc(var(--dd-stage) * 0.026);
	}

	/* Half the width means half the columns - four gift cards in a row would
	   shrink the art past legibility. */
	.dd-map__grid--4 {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	/* Contact's three rows read better stacked than squeezed into three
	   columns at this width, and stacking is what fills the taller console. */
	.dd-map__grid--3 {
		grid-template-columns: minmax(0, 1fr);
	}

	/* The vouchers do the same, for a blunter reason: four of them in a 2x2
	   inside a 520px column made four 293px squares carrying a name and a
	   four-word note each - the emptiest tiles on the page. As rows they fill
	   the same height with the same words and gain an affordance. */
	/* Two classes (0,2,0): the `.dd-map__grid { align-content: stretch }` rule
	   further down this same block is (0,1,0) but LATER, so a one-class
	   selector here silently lost the tie on source order. */
	.dd-map__grid.dd-map__grid--vch {
		grid-template-columns: minmax(0, 1fr);
		/* Rows that divide what the rate line leaves, with a real gap between
		   them. Two earlier attempts were wrong in opposite directions: a bare
		   `1fr` made them 165px tall apiece for two short lines, and
		   `min-content` + space-between sized them to content that no longer
		   fitted, so the fourth spilled 29px out of the console. minmax(0, 1fr)
		   divides and can shrink. */
		grid-auto-rows: minmax(0, 1fr);
		align-content: stretch;
	}

	.dd-map__ent.dd-map__ent--vch {
		flex-direction: row;
		align-items: center;
		justify-content: flex-start;
		gap: 12px;
		min-height: 0;
		padding: 10px 16px;
	}

	.dd-map__ent--vch .dd-map__ent-go {
		display: grid;
	}

	/* Six posts, two columns of three - one column of six at this height gives
	   each row a 55px sliver, which is not enough for a two-line title. */
	.dd-map__posts {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 10px;
	}

	/* Gift cards become rows for exactly the reason the vouchers did one block
	   up: in a ~505px column a 2x2 gave four tiles that were mostly empty
	   gradient, and the panel had nowhere to say what the card costs or which
	   regions it covers. As rows the face keeps its real proportions, the name
	   gets a proper size, and the note fits on the line under it.
	   Two classes (0,2,0) to beat the later `.dd-map__grid { align-content:
	   stretch }` on source order - the same tie --vch lost once. */
	.dd-map__grid.dd-map__grid--art {
		grid-template-columns: minmax(0, 1fr);
		grid-auto-rows: minmax(0, 1fr);
		align-content: stretch;
		flex: 1;
		min-height: 0;
	}

	.dd-map__ent.dd-map__ent--art {
		flex-direction: row;
		align-items: center;
		justify-content: flex-start;
		text-align: initial;
		gap: 13px;
		min-height: 0;
		padding: 10px 14px;
	}

	/* Height-driven, width-derived. The previous rule dropped the aspect ratio
	   altogether because a width-driven 8:5 face demanded 124px inside a 160px
	   row and pushed the pinned console 8px open; with the height taking its
	   share of the row and the width following, that cannot happen and the card
	   keeps ID-1. */
	.dd-map__ent--art .dd-map__face {
		width: auto;
		height: 100%;
		max-height: 76px;
	}

	.dd-map__ent--art .dd-map__ent-nm {
		font-size: 14.5px;
		font-weight: 800;
		letter-spacing: 0.2px;
	}

	.dd-map__ent--art .dd-map__ent-go {
		display: grid;
	}

	.dd-map__ent--art:hover .dd-map__ent-go {
		background: rgba(224, 190, 0, 0.2);
		transform: translateX(-3px);
	}

	/* The panel body absorbs the leftover height and divides it between its
	   rows. Centring small cards in a 521px box instead was tried first and
	   left a band of dead air above and below them; at this size the right
	   answer is not smaller cards floating in space but cards with enough
	   presence to hold the panel - so the type scales up with them below and
	   the crypto panel reads as a price board. */
	.dd-map__grid,
	.dd-map__posts {
		flex: 1;
		align-content: stretch;
		grid-auto-rows: minmax(0, 1fr);
		/* `flex: 1` cannot shrink a flex item below its content while
		   min-height is auto, which is the default. Without this تماس - the
		   only three-row panel - overflowed its pinned console by 23px. */
		min-height: 0;
	}

	/* The perks list takes the slack in the پنل panel; the buttons stay the
	   size of buttons. They used to be in the stretch rule above, which grew
	   them to 750px - two gold slabs with a word in the middle of each. */
	.dd-map__perks {
		flex: 1;
		min-height: 0;
		margin-bottom: 16px;
		/* Spread rather than centred: at this height a centred trio leaves one
		   fat band of nothing above it and reads as a rendering accident. */
		justify-content: space-evenly;
	}

	.dd-map__perks li {
		padding: 11px 2px;
	}

	.dd-map__perks .dd-map__ent-nm {
		font-size: 15px;
	}

	.dd-map__panel-cta {
		flex: none;
	}

	.dd-map__go,
	.dd-map__ghost {
		min-height: 92px;
	}

	.dd-map__grid {
		gap: 12px;
	}

	.dd-map__ent {
		min-height: 108px;
		padding: 14px 16px;
		gap: 8px;
	}

	/* The head is the console's title bar at this size, so it gets the room to
	   look like one. */
	.dd-map__panel-ico {
		width: 40px;
		height: 40px;
		border-radius: 13px;
	}

	.dd-map__panel-ico .dd-map__i {
		width: 22px;
		height: 22px;
	}

	.dd-map__more {
		font-size: 12.5px;
		padding: 7px 12px 7px 9px;
	}

	.dd-map__chg {
		font-size: 11.5px;
		padding: 3px 8px;
	}

	/* At this size the console has a title bar, a description and a body, and
	   the body is the part that changes. A hairline says so - the approved
	   separator, inside the panel, between a statement and what follows it.
	   Two classes to match the base rule's specificity, or the margin below
	   silently keeps the base value. */
	.dd-map .dd-map__panel-lead {
		margin: 0 0 14px;
		padding-bottom: 13px;
		border-bottom: 1px solid var(--m-brd);
	}

	/* Type that matches the larger tile - at the small size these numbers
	   looked stranded in the middle of the card. */
	.dd-map__ent-nm {
		font-size: 15px;
	}

	.dd-map__ent-nm--lg {
		font-size: 16px;
	}

	/* The number is the reason this panel exists, so at this size it is the
	   biggest thing on the card rather than one of three similar lines. */
	.dd-map__price-v {
		font-size: 21px;
		letter-spacing: 0.2px;
	}

	/* The card is tall enough here to carry a chart, and only here. */
	.dd-map__trend {
		display: flex;
	}

	.dd-map__ent-note {
		font-size: 12.5px;
	}

	.dd-map__post-t {
		font-size: 14px;
	}

	/* The orbit sets the row height here, so the CLS guard is redundant and a
	   fixed floor would only fight `height: 100%`. */
	.dd-map__console {
		min-height: 0;
	}
}

/* Very small phones: the orbit would crowd, so tighten the node and its type
   rather than letting the labels wrap. */
@media (max-width: 359px) {
	.dd-map__stage {
		--dd-node: calc(var(--dd-stage) * 0.245);
	}

	.dd-map__node-lb {
		font-size: calc(var(--dd-stage) * 0.033);
	}
}

/* ===========================================================================
 * Dark mode. Only the values that cannot be expressed as tokens are restated;
 * everything else follows --dd-* / --m-* automatically.
 * ======================================================================== */

/* The material, restated for black. Every number here is higher than its light
   counterpart for the same reason: on a near-black ground an 8%-white edge is
   invisible where the same edge on cream is plainly a border. The shadows go
   the other way - a drop shadow on black does nothing, so the separation is
   carried by the edge and the inner highlight instead, and the shadow is only
   there to seat the card.

   ---------------------------------------------------------------------------
   Why every declaration here carries !important, and why the block below it
   exists at all
   ---------------------------------------------------------------------------
   The Dracula dark mode plugin does not just add a scheme - it READS every
   stylesheet on the page and re-emits each rule with the colours mapped to
   dark, into an inline <style> that lands after the enqueued sheets. It cannot
   tell a hand-authored dark rule from a light one, so it "helps" with these
   too: measured on the live page, rgba(255,255,255,.15) came out
   rgba(62,62,59,.15) and every gold in this file came out a desaturated brown.
   That is the real reason the dark section looked flat - the borders were not
   thin, they were being repainted almost the colour of the ground.

   Two defences, and both are needed:

   1. !important on the declaration. The plugin's copy does not carry it, so
      the value here wins the cascade. That fixes the token itself.

   2. The twins. Where a rule CONSUMES one of these tokens, the plugin also
      rewrites the consumer to read its own copy instead -
      `border: 1px solid var(--m-brd)` becomes a reference to
      `--dracula-border--m-brd`, which it declares with the darkened value. So
      each twin is pinned back to the token it shadows. The kinds are the
      plugin's own: bg, bgimg, border, text.

   Verify in the browser, never by reading this file - the stylesheet is not
   what runs. Toggle dark mode and read
   getComputedStyle(document.querySelector('.dd-map__ent')).borderTopColor;
   a near-black value means the plugin won and a twin is missing. */
html[data-dracula-scheme="dark"] section.dd-map {
	--m-brd: rgba(255, 255, 255, 0.15) !important;
	--m-brd-lit: rgba(253, 184, 55, 0.55) !important;
	--m-tile: linear-gradient(180deg, rgba(255, 255, 255, 0.085), rgba(255, 255, 255, 0.028)) !important;
	--m-tile-hover: linear-gradient(180deg, rgba(253, 184, 55, 0.14), rgba(253, 184, 55, 0.05)) !important;
	--m-hi: inset 0 1px 0 rgba(255, 255, 255, 0.08) !important;
	--m-lift: 0 10px 24px -18px rgba(0, 0, 0, 0.9) !important;
	--m-lift-up: 0 18px 34px -18px rgba(0, 0, 0, 1) !important;
	--m-glass: linear-gradient(180deg, rgba(255, 255, 255, 0.062), rgba(255, 255, 255, 0.022)) !important;
	--m-spill: rgba(253, 184, 55, 0.1) !important;
	--m-orbit: rgba(253, 184, 55, 0.18) !important;
	--m-wire: rgba(253, 184, 55, 0.26) !important;
	--m-arc: rgba(253, 184, 55, 0.9) !important;
	--m-arc-glow: rgba(253, 184, 55, 0.5) !important;
	/* The pool is sized in the section's own axes, so its two radii are
	   deliberately unequal - 17% of a 1440px width and 32% of a 774px height
	   are both ~245px, which comes out ROUND. Written as one number for both it
	   was a 1440px-wide smear lying across the orbit, which is what a "glow"
	   looks like when nobody checks the box it is drawn in. */
	--m-ground:
		radial-gradient(17% 32% at var(--m-lamp, 50% 28%), rgba(122, 90, 18, 0.46), rgba(20, 16, 10, 0) 72%),
		radial-gradient(130% 100% at 50% 42%, rgba(0, 0, 0, 0) 38%, rgba(0, 0, 0, 0.55) 100%) !important;

	/* The twins, and they must repeat the LITERAL value - `var(--m-brd)` looks
	   DRYer and silently loses. The plugin rewrites this declaration too, and
	   a var() pointing at a token it has also twinned resolves into a cycle;
	   a cycle makes the custom property invalid at computed-value time, the
	   declaration drops out, and what wins instead is the plugin's own copy of
	   the LIGHT rule - which is how a 12%-black hairline ended up on a black
	   card. Measured, 2026-08-21. A literal has nothing to point at, so the
	   !important simply holds. */
	--dracula-border--m-brd: rgba(255, 255, 255, 0.15) !important;
	--dracula-border--m-brd-lit: rgba(253, 184, 55, 0.55) !important;
	--dracula-border--m-orbit: rgba(253, 184, 55, 0.18) !important;
	--dracula-border--m-arc: rgba(253, 184, 55, 0.9) !important;
	--dracula-bgimg--m-tile: linear-gradient(180deg, rgba(255, 255, 255, 0.085), rgba(255, 255, 255, 0.028)) !important;
	--dracula-bgimg--m-tile-hover: linear-gradient(180deg, rgba(253, 184, 55, 0.14), rgba(253, 184, 55, 0.05)) !important;
	--dracula-bgimg--m-glass: linear-gradient(180deg, rgba(255, 255, 255, 0.062), rgba(255, 255, 255, 0.022)) !important;
	--dracula-bgimg--m-ground:
		radial-gradient(17% 32% at var(--m-lamp, 50% 28%), rgba(122, 90, 18, 0.46), rgba(20, 16, 10, 0) 72%),
		radial-gradient(130% 100% at 50% 42%, rgba(0, 0, 0, 0) 38%, rgba(0, 0, 0, 0.55) 100%) !important;
	--dracula-bg--m-hi: inset 0 1px 0 rgba(255, 255, 255, 0.08) !important;
	--dracula-bg--m-lift: 0 10px 24px -18px rgba(0, 0, 0, 0.9) !important;
	--dracula-bg--m-lift-up: 0 18px 34px -18px rgba(0, 0, 0, 1) !important;
	--dracula-bg--m-spill: rgba(253, 184, 55, 0.1) !important;
	--dracula-bg--m-wire: rgba(253, 184, 55, 0.26) !important;
	--dracula-bg--m-arc-glow: rgba(253, 184, 55, 0.5) !important;
	--dracula-text--m-brd-lit: rgba(253, 184, 55, 0.55) !important;
}

/* Same shape as light: the bloom stays outside the coin's rim. Against black it
   is doing more work (it is the only thing separating the disc from the page)
   so it is carried further out and brighter. */
html[data-dracula-scheme="dark"] .dd-map__core {
	background:
		radial-gradient(closest-side, transparent 56%, rgba(253, 184, 55, 0.22) 78%, transparent 100%);
	box-shadow: 0 18px 56px -26px rgba(253, 184, 55, 0.45);
}

/* The halo is doing more work on black - it is most of what separates the coin
   from the page - so it burns hotter and reaches further. The sheen goes the
   other way: a warm white pool that reads as a highlight on cream reads as a
   blown-out patch on black, so it is pulled well back. */
html[data-dracula-scheme="dark"] .dd-map__core::before {
	background: radial-gradient(closest-side at var(--dd-lit-x) var(--dd-lit-y),
		rgba(253, 184, 55, 0.6),
		rgba(253, 184, 55, 0.22) 46%,
		rgba(253, 184, 55, 0) 76%);
}

html[data-dracula-scheme="dark"] .dd-map__core::after {
	background: radial-gradient(closest-side at var(--dd-lit-x) var(--dd-lit-y),
		rgba(255, 244, 214, 0.26),
		rgba(255, 238, 196, 0.08) 38%,
		rgba(255, 236, 190, 0) 66%);
}

/* On cream the auroras are a warm wash; on black the same wash reads as brown
   paint smeared across the section. Tighter and weaker, they read as light
   again - and the ground behind them is now carrying most of the warmth. */
/* Repositioned, not just dimmed. On cream these two sit half outside the
   section and what shows is a warm wash; on black the same crop reads as a
   pale horizontal BAND lying across the orbit, because the only part of the
   ellipse inside the box is its bottom edge. Pulled fully inside and centred
   on the two things that are actually there - the orbit, and the console under
   or beside it - they go back to being light. The breathing is kept: it is the
   section's only ambient motion and it is what stops a dark page looking like
   a still image. */
html[data-dracula-scheme="dark"] .dd-map__aurora {
	top: 6%;
	right: 4%;
	width: 42%;
	height: 62%;
	background: radial-gradient(closest-side, rgba(253, 184, 55, 0.15), rgba(253, 184, 55, 0.045) 48%, transparent 76%);
}

html[data-dracula-scheme="dark"] .dd-map__aurora--b {
	top: auto;
	right: auto;
	bottom: -6%;
	left: 2%;
	width: 40%;
	height: 48%;
	background: radial-gradient(closest-side, rgba(224, 190, 0, 0.09), rgba(224, 190, 0, 0.025) 54%, transparent 78%);
}

/* No silhouette needed on black - see the note on .dd-map__logo. `filter` is a
   single property, so this must restate the whole stack, not just drop a
   layer. */
html[data-dracula-scheme="dark"] .dd-map .dd-map__logo {
	filter: none;
}

html[data-dracula-scheme="dark"] .dd-map__panel-ico {
	background: rgba(253, 184, 55, 0.15);
	color: var(--dd-gold-bright);
}

html[data-dracula-scheme="dark"] .dd-map__more,
html[data-dracula-scheme="dark"] .dd-map__ent-go {
	background: rgba(253, 184, 55, 0.11);
}

html[data-dracula-scheme="dark"] .dd-map__ent-go {
	color: var(--dd-gold-bright);
}

html[data-dracula-scheme="dark"] .dd-map__ent--row:hover .dd-map__ent-go {
	background: rgba(253, 184, 55, 0.2);
}

html[data-dracula-scheme="dark"] .dd-map__more:hover {
	background: rgba(253, 184, 55, 0.19);
}

html[data-dracula-scheme="dark"] .dd-map__chg--up { background: rgba(30, 169, 124, 0.2); color: #4fd6a8; }
html[data-dracula-scheme="dark"] .dd-map__chg--dn { background: rgba(226, 85, 78, 0.2); color: #ff9a94; }
html[data-dracula-scheme="dark"] .dd-map__chg--sub.dd-map__chg--up,
html[data-dracula-scheme="dark"] .dd-map__chg--sub.dd-map__chg--dn { background: transparent; }

/* The same two greens/reds as the chip above the line - on black the token
   pair is too dark to read as a stroke. */
html[data-dracula-scheme="dark"] .dd-map__trend[data-trend="up"]   { color: #4fd6a8; }
html[data-dracula-scheme="dark"] .dd-map__trend[data-trend="down"] { color: #ff9a94; }

html[data-dracula-scheme="dark"] .dd-map__node.is-on {
	color: #ffe9ad;
	background: linear-gradient(160deg, rgba(253, 184, 55, 0.28), rgba(224, 190, 0, 0.11));
	border-color: rgba(253, 184, 55, 0.55);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.16),
		0 0 0 1px rgba(253, 184, 55, 0.22),
		0 0 34px -6px rgba(253, 184, 55, 0.45);
}

html[data-dracula-scheme="dark"] .dd-map__ico {
	background: rgba(253, 184, 55, 0.15);
	color: var(--dd-gold-bright);
}

html[data-dracula-scheme="dark"] .dd-map__sym {
	background: rgba(253, 184, 55, 0.18);
	color: var(--dd-gold-bright);
}

html[data-dracula-scheme="dark"] .dd-map__more,
html[data-dracula-scheme="dark"] .dd-map__creds-link,
html[data-dracula-scheme="dark"] .dd-map__creds .dd-map__i {
	color: var(--dd-gold-bright);
}

html[data-dracula-scheme="dark"] .dd-map__rate {
	background: linear-gradient(180deg, rgba(253, 184, 55, 0.11), rgba(253, 184, 55, 0.035));
}

html[data-dracula-scheme="dark"] .dd-map__kind--article  { background: rgba(253, 184, 55, 0.18); color: var(--dd-gold-bright); }
html[data-dracula-scheme="dark"] .dd-map__kind--news     { background: rgba(226, 85, 78, 0.2); color: #ff9a94; }
html[data-dracula-scheme="dark"] .dd-map__kind--analysis { background: rgba(96, 152, 240, 0.2); color: #8fb6f0; }

/* ===========================================================================
 * Reduced motion - drop every ambient loop. The spark is the one that matters:
 * without motion the selected wire simply stays lit, which still reads.
 * ======================================================================== */

@media (prefers-reduced-motion: reduce) {

	.dd-map__aurora,
	.dd-map__go-sheen,
	.dd-map__wire.is-on::after {
		animation: none;
	}

	.dd-map__wire.is-on::after {
		display: none;
	}

	.dd-map__panel {
		animation: none;
	}

	.dd-map__node,
	.dd-map__node-in,
	.dd-map__ent,
	.dd-map__go,
	.dd-map__ghost {
		transition: none;
	}

	/* The coin's lighting is kept - it is state, not decoration, and it is
	   the same information the lit wire carries. Only the swing goes: the
	   lit side snaps to the open node instead of travelling to it. */
	.dd-map__stage {
		transition: none;
	}

	.dd-map__node:hover .dd-map__node-in,
	.dd-map__node.is-on .dd-map__node-in {
		transform: none;
	}
}

