/* ==========================================================================
   v3 components
   Built against Figma "Tahadani-Dev" (w4BsFLTtBoluvljxUlu5Vi).
   Every rule cites the node it came from. Values without a node reference are
   derived (states Figma doesn't specify) and are marked DERIVED.

   Depends on tokens.css. Load after it.
   RTL: the site is dir="rtl"; physical left/right below intentionally match
   Figma's absolute positioning for decorative elements only.
   ========================================================================== */

/* ==========================================================================
   Box model
   v3 components are authored for border-box (Figma's heights include strokes:
   the navbar's 2px-bordered CTA is 56px tall overall, not 60). MDB happens to
   set border-box globally today, but relying on that is an accidental
   dependency that breaks the moment MDB is removed in the cleanup phase — and
   it makes the components unusable standalone. Declared here for v3 only, so
   v2 markup is untouched.
   ========================================================================== */

[class*="v3-"], [class*="v3-"]::before, [class*="v3-"]::after { box-sizing: border-box; }

/* ==========================================================================
   Button — node 8440:16271
   Pill, orange, 24px SemiBold, drop shadow + inner bottom bevel, and two
   decorative "shine" arcs at the top corners.
   ========================================================================== */

.v3-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-1);              /* 4px */
	padding: 0 var(--v3-space-3);        /* 12px inline; height is fixed, so the
	                                        12px block padding Figma lists is moot */
	height: var(--v3-btn-h-lg);          /* 56 — Semantic Space/Button/Height/Large */
	white-space: nowrap;                 /* Figma types every label nowrap */
	border: 0;
	border-radius: var(--v3-radius-pill);
	background: var(--v3-bg-brand);
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h4);          /* 24px */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);                 /* Figma "Auto" */
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	overflow: hidden;                    /* keeps the shine arcs inside the pill */
	box-shadow: var(--v3-shadow-btn), var(--v3-bevel-inset);
}

/* Decorative shine arcs. Sizes are the exported asset boxes; the offsets place
   each asset's *leaf* box exactly where Figma puts it. The asset overflows its
   leaf by 4px (large) / 1.75px (small) on every side because of the round stroke
   cap, which is why the offsets below are the Figma values minus that overflow. */
.v3-btn::before,
.v3-btn::after {
	content: "";
	position: absolute;
	pointer-events: none;
	background-repeat: no-repeat;
	background-size: 100% 100%;
}

/* Vector 21 — leaf 22 x 16.103 at right 10px / top 8.95px */
.v3-btn::after {
	top: 4.95px;
	right: 6px;
	width: 30.0015px;
	height: 24.1013px;
	background-image: url("/img/v3/btn-shine-right.svg");
}

/* Vector 22 — leaf 9.634 x 7.052 at left 13.18px / top 8.95px, mirrored */
.v3-btn::before {
	top: 7.2px;
	left: 11.43px;
	width: 13.1383px;
	height: 10.5545px;
	background-image: url("/img/v3/btn-shine-left.svg");
	transform: scaleX(-1);
}

/* --- States — PINNED from the Button component set (6376:3387).
   Hover DARKENS to #dc6f38 (an earlier guess of "brighten" was wrong).
   Disable keeps the drop shadow but DROPS the inner bevel (6376:3945). --- */
.v3-btn:hover, .v3-btn.is-hover { background: var(--v3-orange-hover); }

.v3-btn:active {
	transform: translateY(1px);
	box-shadow: var(--v3-bevel-inset);
}

/* DERIVED: Figma defines no focus ring. Required for keyboard accessibility. */
.v3-btn:focus-visible {
	outline: 2px solid var(--v3-border-green);
	outline-offset: 2px;
}

.v3-btn:disabled,
.v3-btn.is-disabled {
	background: var(--v3-orange-disabled-bg);
	color: var(--v3-orange-disabled-fg);
	box-shadow: var(--v3-shadow-btn);    /* drop shadow stays, bevel does not */
	cursor: not-allowed;
	pointer-events: none;
}

.v3-btn:disabled::before, .v3-btn:disabled::after,
.v3-btn.is-disabled::before, .v3-btn.is-disabled::after { display: none; }

/* ==========================================================================
   Hierarchies. Figma names them Primary / Tertiary / Secondary — note that
   Secondary is the OUTLINED one and Tertiary is the plain white one, which is
   the reverse of what the names suggest. Named by role below to avoid the trap.
   All three carry the same drop shadow + inner bevel; only Primary gets the
   shine arcs.
   ========================================================================== */

/* Tertiary — white fill, orange text (6376:3859) */
.v3-btn--ghost {
	background: var(--v3-bg-surface);
	color: var(--v3-text-accent);
}
.v3-btn--ghost::before, .v3-btn--ghost::after { display: none; }
.v3-btn--ghost:hover, .v3-btn--ghost.is-hover { background: var(--v3-bg-surface); color: var(--v3-orange-hover); }
.v3-btn--ghost:disabled, .v3-btn--ghost.is-disabled {
	background: var(--v3-bg-surface);
	color: var(--v3-orange-disabled-fg);
}

/* Secondary — white fill, orange border (6694:14112).
   Hover fills with the page ground; the border darkening is DERIVED to match
   the -hover text token. */
.v3-btn--outline {
	background: var(--v3-bg-surface);
	color: var(--v3-text-accent);
	border: 1px solid var(--v3-border-orange);
}
.v3-btn--outline::before, .v3-btn--outline::after { display: none; }
.v3-btn--outline:hover, .v3-btn--outline.is-hover {
	background: var(--v3-bg-page);
	color: var(--v3-orange-hover);
	border-color: var(--v3-orange-hover);
}
.v3-btn--outline:disabled, .v3-btn--outline.is-disabled {
	background: var(--v3-bg-surface);
	color: var(--v3-orange-disabled-fg);
	border-color: var(--v3-orange-disabled-fg);
}

/* On-brand outline — PINNED from the navbar's "إلعب الآن" (8556:21732).
   A 2px white border on a transparent ground, with its own drop shadow (no
   bevel). Used wherever a button sits on the orange chrome. */
.v3-btn--on-brand {
	background: transparent;
	color: var(--v3-text-inverse);
	border: 2px solid var(--v3-border-white);
	box-shadow: 0 2px 3px 0 rgba(0, 0, 0, .25);
}
.v3-btn--on-brand::before, .v3-btn--on-brand::after { display: none; }
.v3-btn--on-brand:hover, .v3-btn--on-brand.is-hover { background: rgba(255, 255, 255, .12); }

/* Green solid — used in-game, not part of the component set. */
.v3-btn--green { background: var(--v3-bg-green); }
.v3-btn--green:hover, .v3-btn--green.is-hover { background: var(--v3-green-900); }

/* Circular icon button — the companion in each matrix column. Square by
   construction: width equals the size's height. */
.v3-btn--icon {
	width: var(--v3-btn-h-lg);
	min-width: var(--v3-btn-h-lg);
	padding: 0;
}
.v3-btn--icon.v3-btn--md { width: var(--v3-btn-h-md); min-width: var(--v3-btn-h-md); }
.v3-btn--icon.v3-btn--sm { width: var(--v3-btn-h-sm); min-width: var(--v3-btn-h-sm); }
.v3-btn--icon.v3-btn--xs { width: var(--v3-btn-h-xs); min-width: var(--v3-btn-h-xs); }

/* 48px size — node 7689:1357 (the login form's submit).
   Same padding and bevel; the type drops to 20px and the right shine scales.
   The exported 48px right-shine asset is the 56px glyph scaled uniformly by
   0.8105 (geometry AND stroke), so the same file is reused at the smaller box
   — verified byte-for-byte on the path. The left shine is identical at both
   sizes, so it does not change. */
.v3-btn--md {
	height: var(--v3-btn-h-md);          /* 48 — Figma "Mid" */
	font-size: var(--v3-fs-h5);          /* 20px */
}

/* Small (44) and Xsm (36). The component set types these at 16 / 14
   (Mobile/Body and Mobile/Caption SemiBold). Their shine geometry is not
   exported separately, so the arcs are dropped at these sizes rather than
   guessed at — they are decorative and read as noise below 44px anyway. */
.v3-btn--sm {
	height: var(--v3-btn-h-sm);
	font-size: var(--v3-fs-body);        /* 16px */
}

.v3-btn--xs {
	height: var(--v3-btn-h-xs);
	font-size: var(--v3-fs-caption);     /* 14px */
}

.v3-btn--sm::before, .v3-btn--sm::after,
.v3-btn--xs::before, .v3-btn--xs::after { display: none; }

.v3-btn--md::after {
	top: 5.7105px;
	right: 6.838px;
	width: 24.317px;
	height: 19.5348px;
}

/* Text button — node 7689:1402. No fill, no shadow, no shines. */
.v3-btn--link {
	height: var(--v3-btn-h-md);
	background: none;
	box-shadow: none;
	color: var(--v3-text-accent);
	font-size: var(--v3-fs-body);
}
.v3-btn--link::before, .v3-btn--link::after { display: none; }
.v3-btn--link .v3-btn__muted {
	color: var(--v3-text-secondary);
	font-weight: var(--v3-fw-regular);
}

.v3-btn--block { display: flex; width: 100%; }

/* ==========================================================================
   Form field — node 7689:1349 (group) / 7689:1351 (input, "Component 131")
   The input is a PILL filled with the page ground, not white.
   ========================================================================== */

.v3-field {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-4);              /* 16px */
	align-items: stretch;
}

.v3-field__label {
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);     /* 14px */
	font-weight: var(--v3-fw-medium);
	color: var(--v3-text-neutral);       /* Text/Primary #0a0d12 */
	line-height: var(--v3-lh-auto);
	text-align: right;
}

.v3-input {
	width: 100%;
	height: 56px;
	padding: var(--v3-space-4) var(--v3-space-5);   /* 16px 24px */
	border: 1px solid var(--v3-border-neutral);
	border-radius: var(--v3-radius-pill);
	background: var(--v3-bg-page);
	color: var(--v3-text-primary);       /* DERIVED: Figma only specifies the placeholder */
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
	text-align: right;
}

/* A textarea, which the pill shape cannot hold. Same border, focus ring and
   type as the input; only the height and the radius differ. */
.v3-input--area {
	height: auto;
	min-height: 120px;
	padding: var(--v3-space-4) var(--v3-space-5);
	border-radius: 18px;
	resize: vertical;
	line-height: var(--v3-lh-normal);
}

.v3-input::placeholder {
	color: var(--v3-green-tertiary-subtle);
	opacity: 1;                          /* Firefox dims placeholders by default */
}

/* --- States — PINNED from the Input Field set (6193:18165).
   Focus is ORANGE, not green; error is #f04438, not the darker #aa3028; and
   disabled is a NEUTRAL grey, not a green tint. All three were guessed wrong
   before the component set was read. --- */
.v3-input:focus {
	outline: none;
	border-color: var(--v3-border-orange);           /* Border/Orange */
	box-shadow: 0 0 0 3px rgba(242, 122, 61, .16);   /* DERIVED: ring not in Figma */
}

.v3-input.is-error {
	border-color: var(--v3-error-500);               /* Border/Error */
}

.v3-input.is-success {
	border-color: var(--v3-success-500);             /* Border/Success */
}

.v3-input:disabled {
	background: var(--v3-disabled-bg);
	border-color: var(--v3-disabled-border);
	color: var(--v3-disabled-fg);
	cursor: not-allowed;
}

.v3-field__error {
	font-size: var(--v3-fs-caption);
	color: var(--v3-error-600);                      /* Text/Error-Onbrand subtle */
	text-align: right;
}

.v3-field__hint {
	font-size: var(--v3-fs-caption);
	color: var(--v3-text-tertiary);
	text-align: right;
}

/* ==========================================================================
   Inline text link — node 7689:1454 ("هل نسيت كلمة المرور؟") and 7689:1402
   ("سجل الان"). A link inside running text, as opposed to .v3-btn--link, which
   is a button that looks like one.
   ========================================================================== */

.v3-link {
	color: var(--v3-text-on-brand);      /* #ac572b — Text/Orange/Primary */
	font-weight: var(--v3-fw-medium);
	text-decoration: none;
}

.v3-link:hover, .v3-link:focus-visible {
	color: var(--v3-orange-hover);
	text-decoration: underline;
}

/* The emphasised one — the action at the end of a sentence, drawn solid and
   already underlined. */
.v3-link--accent {
	color: var(--v3-text-accent);        /* #f27a3d */
	font-weight: var(--v3-fw-semibold);
	text-decoration: underline;
}

/* ==========================================================================
   Form card — nodes 7741:1692 (تواصل معنا), 7689:1343 (تسجيل الدخول),
   7720:6620 (انشاء حساب), 7747:7415 (الحساب)

   One white panel centred on the cream ground. Every form surface in v3 is this
   card and differs only in what it holds, so the width, padding, radius and
   shadow live here rather than on any one page.
   ========================================================================== */

.v3-formcard {
	width: min(608px, 100%);
	margin: 0 auto;
	padding: var(--v3-space-5) 32px;     /* 24 block / 32 inline — node 7689:1435 */
	border: 1px solid var(--v3-border-green-off);
	border-radius: 24px;
	background: var(--v3-bg-surface);    /* #fefefe */
	box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .06), 4px 4px 12px 0 rgba(0, 0, 0, .06);
}

.v3-formcard__head {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-4);              /* 16px */
	color: var(--v3-green-900);
	text-align: center;
}

.v3-formcard__head h1 {
	margin: 0;
	font-size: var(--v3-fs-h3);          /* 32px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
}

.v3-formcard__head p {
	margin: 0;
	font-size: var(--v3-fs-h5);          /* 20px Medium */
	font-weight: var(--v3-fw-medium);
	/* Figma draws this line 24 tall on a 20px font — auto, not 1.5. At 1.5 the
	   heading block came out 84 against its 78 and pushed everything below it
	   6px down the card. Same on تواصل معنا, whose two lines are 48 (2 x 24). */
	line-height: var(--v3-lh-auto);
}

/* ==========================================================================
   Social chip — node 8112:10783

   The light chip that carries a social glyph, on تواصل معنا and on the account
   page. The footer's is a different thing: dark, and its glyphs are white.
   ========================================================================== */

.v3-social-chip {
	display: grid;
	place-items: center;
	width: 48px;
	height: 48px;
	border: .96px solid var(--v3-border-green-off);
	border-radius: 16.8px;
	background: var(--v3-green-100);     /* Bg/Green/Primary — #e6edeb */
	transition: background-color .15s ease, border-color .15s ease;
}

.v3-social-chip:hover {
	border-color: var(--v3-border-orange);
	background: var(--v3-orange-050);
}

/* The glyph files are filled white, which is right in the footer — the chip is
   dark there — and all but invisible on this one. Figma fills them #064e3b
   here, so they are drawn as a mask and the colour comes from CSS. */
.v3-social-chip__icon {
	width: 24px;
	height: 24px;
	background: var(--v3-bg-green);      /* #064e3b */
	-webkit-mask: no-repeat center / contain;
	mask: no-repeat center / contain;
}

/* intl-tel-input renders its own country selector in front of the control, and
   it appears in every form card that asks for a phone number.

   Node 7720:10877 draws it as a filled chip INSIDE the pill rather than a bare
   flag: measured off the reference, 75 x 34 in a 56-tall control, inset 13 from
   the leading edge, in Bg/Green/default. The plugin inline-styles the container
   to left:0, so the offsets go on the button as margins rather than fighting
   that with !important. */
.v3-formcard .iti { display: block; width: 100%; }

.v3-formcard .iti__selected-country {
	direction: ltr;                      /* or the dial code reads "966+" */
	height: 34px;
	margin: 11px 0 11px 13px;
	padding: 0 var(--v3-space-2);
	border-radius: var(--v3-radius-pill);
	background: var(--v3-bg-green);
	color: var(--v3-text-inverse);
}

.v3-formcard .iti__selected-country:hover,
.v3-formcard .iti__selected-country:focus {
	background: var(--v3-green-850);
}

.v3-formcard .iti__selected-country-primary { gap: var(--v3-space-1); }

.v3-formcard .iti__selected-dial-code {
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	font-weight: var(--v3-fw-semibold);
}

/* The plugin points the arrow with a border triangle in its own colour. */
.v3-formcard .iti__arrow { border-top-color: var(--v3-text-inverse); }

/* Clear of the chip: 13 + 75 + 8. */
.v3-formcard .iti > .v3-input { padding-left: 96px; }

/* A password field with a reveal toggle. The eye sits INSIDE the pill at its
   physical left, which is where an RTL input ends — node 7689:1353. */
.v3-field--reveal {
	position: relative;
}

.v3-field--reveal .v3-input {
	padding-left: 56px;                  /* clear of the toggle */
}

.v3-reveal {
	position: absolute;
	left: 20px;
	bottom: 0;
	display: grid;
	place-items: center;
	width: 24px;
	height: 56px;                        /* the control height, so it centres */
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.v3-reveal::before {
	content: "";
	width: 19px;
	height: 12px;
	background: var(--v3-green-800);
	opacity: .7;                         /* Figma ships the glyph at .7 */
	-webkit-mask: url("/img/v3/eye.svg") no-repeat center / contain;
	mask: url("/img/v3/eye.svg") no-repeat center / contain;
	transition: opacity .15s ease;
}

.v3-reveal:hover::before { opacity: 1; }

/* Revealed: the glyph goes solid, so the control reads as "on" without needing
   a second asset. Figma draws no second state. */
.v3-reveal.is-on::before {
	opacity: 1;
	background: var(--v3-orange-500);
}

/* ==========================================================================
   Wave divider — node 8440:16208 ("Ellipse 131"), also 8717:8340, 8728:8385
   A flattened ellipse in the page colour, overlapping the bottom of an orange
   section. Exported at 1471x180 with preserveAspectRatio="none", i.e. the
   designer intends it to stretch to the section width.

   The exported SVG has its fill baked in as #F4FCE2, which would hard-code the
   colour at three different placements. So the asset is used as a MASK instead
   of an <img> — exact Figma geometry, but the colour stays a token and the
   shape still stretches. Where masks are unsupported, an ellipse via
   border-radius is a close approximation of the same shape.
   ========================================================================== */

/* The ellipse is 180px tall but only its TOP arc should be visible: in the hero
   (8440:16208) it spans y 875..1055 inside a 989px section, so it hangs 66px
   past the bottom edge and the section clips the rest. Visible arc = 114px.
   Override --v3-wave-drop for placements that sit differently. */
.v3-wave {
	--v3-wave-drop: 66px;

	position: absolute;
	left: 50%;
	bottom: calc(-1 * var(--v3-wave-drop));
	transform: translateX(-50%);
	width: 102.15%;                      /* 1471 / 1440 — the asset overhangs the frame */
	height: 180px;
	pointer-events: none;
	background: var(--v3-bg-page);
	border-radius: 50%;                  /* fallback shape */
}

@supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
	.v3-wave {
		border-radius: 0;
		-webkit-mask: url("/img/v3/wave.svg") no-repeat center / 100% 100%;
		mask: url("/img/v3/wave.svg") no-repeat center / 100% 100%;
	}
}

/* Colour variants — the mask means any token works as the wave's fill. */
.v3-wave--page    { background: var(--v3-bg-page); }
.v3-wave--white   { background: var(--v3-bg-surface); }
.v3-wave--brand   { background: var(--v3-bg-brand); }

/* The section a wave sits in must clip it and establish positioning. */
.v3-wave-section {
	position: relative;
	overflow: hidden;
}

/* ==========================================================================
   FAQ accordion — node 8440:16268 (expanded) / 8440:16269 (collapsed)
   ========================================================================== */

.v3-faq {
	display: flex;
	flex-direction: row-reverse;         /* Figma's LTR export lists the toggle
	                                        first (= left there). In RTL that
	                                        lands right, so the row is reversed
	                                        to put the toggle back on the left. */
	align-items: center;
	justify-content: space-between;
	gap: var(--v3-space-5);
	width: 100%;
	padding: var(--v3-space-7) var(--v3-space-8);   /* 40px 48px */
	/* Figma's collapsed card is exactly 136 tall = 40 + 56 + 40: its stroke is
	   drawn INSIDE and adds no height, whereas a CSS border would make it 138
	   and push every later section down. An inset shadow gives the same 1px
	   line, follows the radius, and costs no layout. */
	border: 0;
	box-shadow: inset 0 0 0 1px var(--v3-border-green);
	border-radius: var(--v3-radius-faq);
	background: var(--v3-bg-faq);
	overflow: hidden;
	text-align: right;
	cursor: pointer;
}

.v3-faq__toggle {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background: var(--v3-bg-green);
}

.v3-faq__toggle img {
	display: block;
	width: 40px;
	height: 40px;
	transition: transform .2s ease;      /* DERIVED */
}

.v3-faq__body {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;             /* right, in RTL */
	gap: 20px;                           /* literal: Figma says 20px, which is off the 8pt grid */
	font-size: var(--v3-fs-h3);          /* 32px */
	line-height: var(--v3-lh-auto);
}

.v3-faq__q {
	font-weight: var(--v3-fw-semibold);
	color: var(--v3-text-secondary);
}

.v3-faq__a {
	width: 100%;
	font-weight: var(--v3-fw-regular);
	color: var(--v3-text-tertiary);
}

/* Collapsed — node 8440:16269 is the same card at 136px with no answer body */
.v3-faq.is-collapsed .v3-faq__a { display: none; }
.v3-faq.is-collapsed .v3-faq__toggle img { transform: rotate(180deg); }

/* ==========================================================================
   Card — the white content card behind questions (7982:12719, 8440:14185)
   ========================================================================== */

.v3-card {
	background: var(--v3-bg-surface);
	border: 1px solid var(--v3-border-green);
	border-radius: var(--v3-radius-lg);
	padding: var(--v3-space-5);
}

/* ==========================================================================
   Pills & badges — in-game chrome (7982:12719)
   ========================================================================== */

.v3-pill {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-2);
	padding: var(--v3-space-2) var(--v3-space-4);
	border-radius: var(--v3-radius-pill);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
}

/* Category pill — muted green on a translucent ground */
.v3-pill--category {
	background: var(--v3-green-300);
	color: var(--v3-text-secondary);
}

/* Points badge and timer — solid dark green */
.v3-pill--score,
.v3-pill--timer {
	background: var(--v3-bg-green);
	color: var(--v3-text-inverse);
}

.v3-pill--timer { font-size: var(--v3-fs-h5); }

/* ==========================================================================
   Tick badge — node 6432:21310 ("Check")
   A 20px round selection indicator, NOT a form checkbox. Two colour variants.
   The glow shadows are bound to the LEGACY v2 orange / the green — reproduced
   exactly as designed.
   ========================================================================== */

.v3-check {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border-radius: var(--v3-radius-pill);
	background: var(--v3-icon-orange);
	box-shadow: 0 2px 3px rgba(254, 117, 39, .5);   /* legacy orange glow, per Figma */
}

.v3-check::after {
	content: "";
	width: 14px;
	height: 14px;
	background: var(--v3-icon-white);
	-webkit-mask: url("/img/v3/tick.svg") no-repeat center / 100% 100%;
	mask: url("/img/v3/tick.svg") no-repeat center / 100% 100%;
}

.v3-check--green {
	background: var(--v3-green-icon);               /* #054736 */
	box-shadow: 0 2px 3px rgba(6, 78, 59, .5);
}

/* ==========================================================================
   Segmented control — node 8483:10778 ("Switch")
   The game switcher: الالعاب الجماعية / وصلها. A dark green track with one
   light active segment. Not a boolean toggle.
   ========================================================================== */

.v3-segmented {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-1);              /* 4px */
	height: 72px;
	padding: 6px var(--v3-space-3);      /* 6px 12px */
	border-radius: 40px;
	background: var(--v3-bg-green);
	overflow: hidden;
}

.v3-segmented__item {
	flex: 1 0 0;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	height: 100%;
	padding: 10px;
	border: 0;
	border-radius: 32px;
	background: transparent;
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h5);          /* 20px */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	cursor: pointer;
}

.v3-segmented__item.is-active {
	background: var(--v3-bg-page);
	color: var(--v3-text-secondary);
	cursor: default;
}

/* The same decorative arc family as the button, at the track's top-left.
   Leaf 9.5 x 5.03 at right 502.5 / top 7.47; the asset overhangs by 1.5px
   horizontally and 1.5px vertically. Figma anchors it to the right edge of a
   527px track, which puts it 13.5px from the LEFT — measured that way it lands
   in the same place and holds at any track width. */
.v3-segmented::after {
	content: "";
	position: absolute;
	top: 5.97px;
	left: 13.5px;
	width: 12.5px;
	height: 8.03px;
	background: url("/img/v3/switch-shine.svg") no-repeat center / 100% 100%;
	transform: scaleX(-1);
	pointer-events: none;
}

/* ==========================================================================
   Search pill — the "Search web" instance, 453 x 56 on the category pages and
   the previous-game ones (8556:20184, 8556:20501, 8440:14018).

   Was written out three times, once per page stylesheet, and two of those had
   it WHITE. It is not: the fill samples #f4fce2 in every frame, the same ground
   the page sits on, so the pill reads as an outline rather than a card. The
   placeholder is 16px too — 15px of ink against the 13 a 14px face gives.

   The margin above it differs per page, so that stays with the page.
   ========================================================================== */

.v3-search {
	display: flex;
	align-items: center;
	gap: var(--v3-space-3);
	height: 56px;
	padding: 0 var(--v3-space-5);
	border: 1px solid var(--v3-border-green);
	border-radius: var(--v3-radius-pill);
	background: var(--v3-bg-page);
}

.v3-search__icon {
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	background: var(--v3-green-800);
	-webkit-mask: url("/img/v3/search.svg") no-repeat center / contain;
	mask: url("/img/v3/search.svg") no-repeat center / contain;
}

.v3-search input {
	flex: 1 1 auto;
	min-width: 0;
	height: 100%;
	border: 0;
	background: none;
	color: var(--v3-text-primary);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);        /* 16 — the ink measures 15 */
	text-align: right;
	outline: none;
}

.v3-search input::placeholder { color: var(--v3-green-tertiary-subtle); }
.v3-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ==========================================================================
   Team picker — node 7940:9592 ("Choose")
   Glassmorphic card holding three player slots: filled slots get a solid
   border, empty ones a dashed border with a "+" glyph.
   NOTE: the selected-slot border and Team 1's "+" are bound to the LEGACY
   orange #fe7527, while everything else in v3 uses #f27a3d.
   ========================================================================== */

.v3-team-picker {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 26px;
	height: 147px;
	padding: 27.748px 35.748px;
	border: 1.748px solid rgba(255, 255, 255, .7);
	border-radius: 42px;
	background: rgba(255, 255, 255, .55);
	box-shadow: 0 21.851px 65.552px 0 rgba(31, 81, 48, .18);
}

.v3-team-picker__slots {
	display: flex;
	align-items: center;
	gap: 17.481px;
}

.v3-team-picker__slot {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 80px;
	height: 80px;
	padding: 3.048px;
	border: 3.048px dashed rgba(254, 117, 39, .6);
	border-radius: 19.048px;
	overflow: hidden;
}

.v3-team-picker__slot::after {
	content: "";
	width: 34.2857px;
	height: 34.2857px;
	background: var(--v3-orange-legacy);
	-webkit-mask: url("/img/v3/plus.svg") no-repeat center / 100% 100%;
	mask: url("/img/v3/plus.svg") no-repeat center / 100% 100%;
}

.v3-team-picker__slot.is-filled {
	border-style: solid;
	border-color: var(--v3-orange-legacy);
	padding: 3.048px;
}
.v3-team-picker__slot.is-filled::after { display: none; }

.v3-team-picker__slot img {
	width: 100%;
	height: 73.905px;
	object-fit: cover;
	border-radius: 16px;
}

.v3-team-picker__label {
	font-size: var(--v3-fs-h4);          /* 24px */
	font-weight: var(--v3-fw-bold);
	color: var(--v3-text-on-brand);      /* #ac572b */
	white-space: nowrap;
}

/* Team 2 — green */
.v3-team-picker--green .v3-team-picker__slot { border-color: rgba(6, 78, 59, .6); }
.v3-team-picker--green .v3-team-picker__slot::after { background: var(--v3-green-icon); }
.v3-team-picker--green .v3-team-picker__slot.is-filled { border-color: var(--v3-border-green); }
.v3-team-picker--green .v3-team-picker__label { color: var(--v3-text-secondary); }

/* ==========================================================================
   Navbar (marketing) — node 8556:21983
   An orange bar whose bottom edge is a shallow wave — a DIFFERENT shape from
   the hero's ellipse divider. Shipped as its own SVG ("Vector 30") with the
   fill and a small inner shadow baked in, plus an outer drop shadow on the
   whole bar. Used as a background image rather than a mask: the navbar is
   always orange, and masking would discard the SVG's built-in shadow.

   Layout is logo / menu / burger. `.v3-navbar__menu` is display:contents on
   desktop so links and actions act as direct flex children (matching Figma),
   and becomes a dropdown panel on phones.
   ========================================================================== */

/* FIXED, SO THE BAR SURVIVES THE WHOLE PAGE.

   sticky was the obvious answer and it does not work here: a sticky element is
   constrained by its PARENT box, and on the home page and both game landings
   the navbar is a child of the hero. It stuck perfectly — to the hero — and
   left the screen with it after 878px. That is not an overflow problem and no
   amount of declipping fixes it.

   So the bar is taken out of the flow, and .v3-navbar-rail is left behind
   holding exactly the height it used to occupy. Every page keeps the layout it
   had, including the two where the bar sits inside a hero that measured its own
   padding around it.

   ONE HEIGHT, THREE PLACES. The rail and the bar have to agree at every
   breakpoint or the page jumps, so the number lives in --v3-nav-h and both read
   it. Setting it twice was the mistake waiting to happen.

   The bar paints its own orange through ::before, masked to the wave, so it is
   opaque wherever it ends up: over the hero it is orange on orange, and over a
   page body it is the same wavy bar the non-hero pages already show at rest.

   Neither hero carries a transform or a filter, so nothing captures the fixed
   positioning — checked, because either would silently pin it to the hero again.

   The game bar opts out below: that screen does not scroll. */
:root { --v3-nav-h: 111px; }

/* An in-page jump must not land UNDER the fixed bar. The footer’s طريقة اللعب
   goes to /trivia-game#how, and without this the كيف تلعب heading arrives
   exactly beneath the bar that is covering it. */
html { scroll-padding-top: var(--v3-nav-h); }

.v3-navbar-rail { height: var(--v3-nav-h); }

.v3-navbar {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 40;
	height: var(--v3-nav-h);
	width: 100%;
	padding-top: 15px;                   /* Figma: 72px row starting at y=15.
	                                        Padding, NOT a margin on the inner —
	                                        a top margin collapses out of this
	                                        block and shifts the whole bar down. */
}

.v3-navbar__state { position: absolute; opacity: 0; pointer-events: none; }

/* Only rendered once the nav collapses (see the 900px block). */
.v3-navbar__scrim { display: none; }

/* The bar itself, wavy bottom edge included — not an overlay on a background,
   which is why a page with no hero needs nothing behind it.

   Drawn as a MASK over a flat brand fill rather than as the exported SVG. That
   file carries its own drop-shadow filter, and a filtered SVG subtree is
   rasterised at the file's intrinsic size and then scaled to the element, so
   the edge went soft and stepped once the cream page put it against something
   that showed it. The mask is just the path, so it rasterises at device
   resolution, and the shadow comes from CSS. */
.v3-navbar::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: var(--v3-bg-brand);
	-webkit-mask: url("/img/v3/navbar-wave-mask.svg") no-repeat center / 100% 100%;
	mask: url("/img/v3/navbar-wave-mask.svg") no-repeat center / 100% 100%;
	filter: drop-shadow(0 6px 18px rgba(0, 0, 0, .25));
	pointer-events: none;
}

/* 21, and it has to be 21 at EVERY width, not just on a phone.

   .v3-navbar is position:relative with no z-index, so it is not a stacking
   context — its children compete at the root, and __inner at 1 took the whole
   navbar subtree with it, profile menu included. Any positioned thing on the
   page with a z-index above 1 then painted over the open dropdown, which is
   what the category cards' heart, info and count buttons were doing.

   The band is the one 71 sets out: page content 0..3, fixed page furniture
   4..20, the navbar 21..30, dialogs 999+. The mobile block used to raise this
   on its own; now it inherits. */
.v3-navbar__inner {
	position: relative;
	z-index: 21;
	display: flex;
	align-items: center;
	gap: 44px;                           /* Figma gap between logo and links */
	height: 72px;
	margin: 0 auto;
	padding: 0 100px;
	max-width: 1440px;
}

.v3-navbar__menu { display: contents; }

.v3-navbar__logo-link { display: block; flex: 0 0 auto; line-height: 0; }

.v3-navbar__logo {
	display: block;
	width: 143.549px;
	height: 51.756px;
	object-fit: contain;
}

.v3-navbar__links {
	display: flex;
	align-items: center;
	gap: var(--v3-space-5);              /* 20px */
}

.v3-navbar__link {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 14px var(--v3-space-2);     /* 14px 8px */
	border: 0;
	border-bottom: 3px solid transparent;
	background: none;
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h4);          /* 24px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	text-decoration: none;
	cursor: pointer;
}

.v3-navbar__link.is-active { border-bottom-color: var(--v3-border-white); }

/* DERIVED: Figma defines no hover for nav links. */
.v3-navbar__link:hover { border-bottom-color: var(--v3-border-white-subtle); }

/* Auth actions sit at the far end. 402px total, two equal buttons, 20px gap. */
.v3-navbar__actions {
	display: flex;
	align-items: center;
	gap: var(--v3-space-5);              /* 20px */
	width: 402px;
	margin-inline-start: auto;           /* push to the end (left in RTL) */
}

.v3-navbar__actions .v3-btn {
	flex: 1 0 0;
	min-width: 0;
	font-size: var(--v3-fs-title);       /* 18px, not the 24px page default */
}

/* --- Burger. DERIVED: no phone navbar exists in Figma. --- */
.v3-navbar__burger {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 48px;
	height: 48px;
	padding: 12px;
	margin-inline-start: auto;
	border-radius: var(--v3-radius-md);
	cursor: pointer;
}

.v3-navbar__burger span {
	display: block;
	height: 3px;
	border-radius: 2px;
	background: var(--v3-white);
	transition: transform .2s ease, opacity .2s ease;
}

/* ==========================================================================
   Navbar — in-game variant, node 8556:21517 ("Nav bar Game")
   Same wave background (the export differs from the marketing one only by
   Figma's auto-generated filter ids — geometry, fill and shadow are identical,
   so a single asset serves both). Differences that matter:
     - the logo is CENTRED and larger (196x71 vs 143.5x51.8)
     - the right side carries the team name + a turn pill
     - the left side is mostly borderless text buttons
   ========================================================================== */

/* The board fills the viewport and does not scroll, so its bar is part of a
   grid rather than something to keep in view. Back to the flow, and back to its
   own height — the game bar has never been 111. */
.v3-navbar--game { position: relative; z-index: auto; height: 111px; }

/* THE GAME BAR IS AS WIDE AS THE GAME, not as wide as a marketing page.

   .v3-navbar__inner caps itself at 1440 and centres, which is right for the
   marketing pages — a reading column should not stretch to a 2560 monitor. The
   game is not a reading column: both boards lay out against a viewport-
   proportional gutter and fill the screen. So on a wide monitor the bar's
   controls were penned into 1440 while the board beneath them ran to 1696
   (at 1920) or 1647 (at 2560), leaving the actions and the status huddled
   around the centred logo with a stripe of empty orange out to each edge.

   Matching the trivia board's own 5.83vw gutter puts the controls back over the
   content they belong to. The clamp keeps it sane at both ends: never tighter
   than 24px, and never past وصلها's 190px cap, so one bar suits both boards. */
.v3-navbar--game .v3-navbar__inner {
	justify-content: space-between;
	max-width: none;
	padding-inline: clamp(24px, 5.83vw, 190px);
}

.v3-navbar__logo--center {
	position: absolute;
	left: 50%;
	top: 20px;
	transform: translateX(-50%);
	z-index: 1;
	width: 196px;
	height: 71px;
	object-fit: contain;
}

/* Right side: team name + whose-turn pill */
.v3-navbar__game-status {
	display: flex;
	align-items: center;
	gap: var(--v3-space-2);              /* 8px */
}

.v3-navbar__team {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 14px var(--v3-space-5);     /* 14px 20px */
	border-radius: 40px;
	color: var(--v3-text-inverse);
	font-size: var(--v3-fs-h4);          /* 24px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
}

/* The outlined in-bar pill. The board carries two — the whose-turn control on
   the right (8031:12613) and إنهاء اللعبة on the left (8031:12487) — with
   identical fill, border, shadow and type; only the width differs. One rule,
   because a component duplicated per user is a component that drifts (§70). */
.v3-navbar__turn,
.v3-navbar__pill {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-2);
	height: 56px;
	padding: var(--v3-space-3);
	border: 1px solid var(--v3-border-white);   /* 1px here, unlike the 2px CTA */
	border-radius: var(--v3-radius-pill);
	background: transparent;
	box-shadow: 0 2px 3px 0 rgba(0, 0, 0, .25);
	color: var(--v3-orange-050);         /* Text/Orange/Primary-Subtle, not pure white */
	font-family: var(--v3-font);
	font-size: var(--v3-fs-title);       /* 18px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	cursor: pointer;
}

.v3-navbar__turn { width: 235px; }

.v3-navbar__turn img,
.v3-navbar__pill img { display: block; width: 24px; height: 24px; }

/* DERIVED: Figma draws no hover for either — the same wash as __text-btn. */
.v3-navbar__turn:hover,
.v3-navbar__pill:hover { background: rgba(255, 255, 255, .12); }

/* __pill is used on an <a> as well as a <button> — the finish's "العب مرة
   ثانية" is a link. MDB's `a:hover { color: rgb(14,82,193) }` is (0,1,1) and
   beats one class, so the colour has to be restated in every link state and not
   only in the base rule. §25. */
.v3-navbar__pill:link, .v3-navbar__pill:visited, .v3-navbar__pill:hover,
.v3-navbar__pill:focus, .v3-navbar__pill:active {
	color: var(--v3-orange-050);
	text-decoration: none;
}

/* Left side: 490px of actions, mostly borderless text buttons */
.v3-navbar__game-actions {
	display: flex;
	align-items: center;
	/* flex-END, which in RTL is the physical LEFT. With two or three actions the
	   children fill the 490 and it changes nothing; the finish has only خروج,
	   and without this that one button sits at the group's right edge instead
	   of the far left where every frame draws it. */
	justify-content: flex-end;
	gap: var(--v3-space-5);              /* 20px */
	width: 490px;
	height: 72px;
}

/* 235 is what two of them come to in a 490 group, and no frame draws one wider.
   Three share it at 150 each, which is under the cap and so unaffected. */
.v3-navbar__game-actions > * { flex: 1 0 0; min-width: 0; max-width: 235px; }

.v3-navbar__game-actions .v3-btn { font-size: var(--v3-fs-title); }

/* Borderless in-bar text button — no fill, no border, no shadow */
.v3-navbar__text-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-2);
	height: 56px;
	padding: var(--v3-space-3);
	border: 0;
	border-radius: var(--v3-radius-pill);
	background: transparent;
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-title);       /* 18px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	cursor: pointer;
}

/* DERIVED: Figma defines no hover for these. */
.v3-navbar__text-btn:hover { background: rgba(255, 255, 255, .12); }

/* ==========================================================================
   Footer — node 8440:16312
   Orange block with a SINE-WAVE top edge (4 periods) — a third wave shape,
   distinct from both the hero ellipse and the navbar's shallow wave.
   Shipped as two vectors: a near-rectangular body and the 38.26px wave band
   that sits directly above it. The body is reproduced with a token background;
   only the wave needs the asset, masked so its fill stays tokenized.
   ========================================================================== */

.v3-footer {
	position: relative;
	margin-top: 10px;                    /* Figma: orange body starts 10px below
	                                        the previous section, so the 38.26px
	                                        wave laps 28.26px over it */
	background: var(--v3-bg-brand);
	color: var(--v3-text-inverse);
}

/* THE WAVE OVERLAPS THE FOOTER BY A PIXEL, ON PURPOSE.

   Its height was exactly 38.2628px sitting at exactly -38.2628px, so its bottom
   edge and the footer's top edge were the same fractional coordinate. At 1x they
   round together and the join is invisible — which is why neither of us could
   reproduce this. At a fractional device pixel ratio they need not: the wave can
   round up to one device pixel and the footer down to the next, and the cream
   page shows through the 1px between them as a white line across the full width.
   Staff on a MacBook saw exactly that.

   The extra pixel is painted the same orange as both neighbours, so it cannot be
   seen at any ratio — it only removes the chance of a gap. Nudging the numbers
   would have moved the seam rather than closed it. The mask still maps to the
   wave's own 38.2628px through mask-size, so the curve does not stretch. */
.v3-footer::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -38.2628px;
	/* ONE PIXEL TALLER THAN THE WAVE, so it overlaps the footer instead of
	   abutting it.

	   At 38.2628px the wave's bottom edge and the footer's top edge were the same
	   fractional coordinate. At 1x they round to the same device pixel and the
	   join is seamless — which is why neither the owner nor I could reproduce
	   this. At a fractional device pixel ratio they need not: the wave can round
	   up to one device pixel and the footer down to the next, and the cream page
	   shows through the row between them as a white line across the full width.
	   Staff on a MacBook saw exactly that.

	   footer-wave.svg closes its path with "V38.2628 H0" — the fill runs solid to
	   the bottom edge across the whole width — and preserveAspectRatio is none, so
	   stretching it 1px taller carries that solid edge a pixel INTO the footer.
	   The overlap is orange on orange and cannot be seen at any ratio; the curve
	   grows 2.6% taller, which cannot either. Nudging the numbers would have moved
	   the seam rather than closed it. */
	height: 39.2628px;
	background: var(--v3-bg-brand);
	-webkit-mask: url("/img/v3/footer-wave.svg") no-repeat center / 100% 100%;
	mask: url("/img/v3/footer-wave.svg") no-repeat center / 100% 100%;
	pointer-events: none;
}

.v3-footer__inner {
	display: flex;
	flex-direction: column;
	gap: 57px;
	max-width: 1241px;
	margin: 0 auto;
	padding: 40px 0 0;
}

.v3-footer__top {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	width: 100%;
}

/* --- Brand block (first in DOM => right in RTL) --- */
/* Figma's export says items-end, but that is LTR code describing an RTL
   design: in RTL, flex-end resolves to the LEFT. Everything in the brand
   column hugs the RIGHT edge, so it is flex-start here. */
.v3-footer__brand {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 18px;
}

/* The wordmark, sized by height so the logo's own aspect ratio decides its
   width — it replaced a square 68x66 favicon, and pinning both axes on a wide
   mark would squash it. */
.v3-footer__mark {
	display: block;
	width: auto;
	max-width: 240px;
	height: 66px;
	object-fit: contain;
}

.v3-footer__tagline {
	margin: 0;
	font-size: var(--v3-fs-h4);          /* 24px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	text-align: right;
}

/* The supporting line §3 pairs with the slogan. Figma had no second line here —
   it padded the gap with an empty paragraph instead, which this now fills with
   actual words, so the 28.2px that used to be blank margin is real content. */
.v3-footer__sub {
	margin: 6px 0 0;
	font-size: var(--v3-fs-body);
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
	text-align: right;
	opacity: .85;
}

.v3-footer__socials {
	display: flex;
	align-items: flex-start;
	gap: var(--v3-space-2);              /* 8px */
}

.v3-footer__social {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border: 0.96px solid var(--v3-border-dark-subtle);
	border-radius: 16.8px;
	background: rgba(0, 0, 0, .25);
}

.v3-footer__social img { display: block; width: 24px; height: 24px; }

/* DERIVED: Figma defines no hover for either the social chips or the store
   badges. They sit side by side, so they deepen by the same amount. */
.v3-footer__social,
.v3-footer__store { transition: background-color .15s ease, border-color .15s ease; }

.v3-footer__social:hover { background: rgba(0, 0, 0, .4); }
.v3-footer__store:hover  { background: rgba(0, 0, 0, .45); }

.v3-footer__stores {
	display: flex;
	align-items: center;
	justify-content: flex-start;         /* right, in RTL */
	gap: var(--v3-space-2);
	height: 56.1px;
}

.v3-footer__store {
	display: flex;
	align-items: center;
	gap: var(--v3-space-2);
	height: 100%;
	padding: 8.8px 12.8px;
	border: 0.8px solid var(--v3-border-dark-subtle);
	border-radius: 14px;
	background: rgba(0, 0, 0, .3);
	text-decoration: none;
	color: var(--v3-text-inverse);
	direction: ltr;                      /* Latin label + leading glyph */
	text-align: left;
}

.v3-footer__store img { display: block; width: 20px; height: 20px; }

.v3-footer__store-text {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-1);              /* 4px */
	line-height: var(--v3-lh-auto);
}

.v3-footer__store-text small {
	font-size: var(--v3-fs-m-small);     /* 12px */
	font-weight: var(--v3-fw-regular);
	color: rgba(255, 255, 255, .7);
}

.v3-footer__store-text strong {
	font-size: var(--v3-fs-caption);     /* 14px */
	font-weight: var(--v3-fw-semibold);
}

/* --- Link columns --- */
.v3-footer__cols {
	display: flex;
	align-items: flex-start;
	justify-content: flex-start;         /* right, in RTL */
	gap: 60px;
}

.v3-footer__col {
	display: flex;
	flex-direction: column;
	align-items: flex-start;             /* right, in RTL */
	gap: var(--v3-space-5);              /* 24px */
	width: 160px;
}

.v3-footer__heading {
	width: 100%;
	margin: 0;
	padding: 8px 0 8.8px;
	border-bottom: 0.8px solid var(--v3-border-white-subtle);
	font-size: var(--v3-fs-h4);          /* 24px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	text-align: right;
}

.v3-footer__links {
	display: flex;
	flex-direction: column;
	align-items: flex-start;             /* right, in RTL */
	gap: var(--v3-space-3);              /* 12px */
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
}

.v3-footer__links a {
	display: block;
	width: 100%;
	padding: 6px 0;
	color: var(--v3-text-inverse);
	font-size: var(--v3-fs-h4);          /* 24px Medium */
	font-weight: var(--v3-fw-medium);
	line-height: 38px;                   /* Web/H4: Medium carries an explicit 38px */
	text-align: right;
	text-decoration: none;
}

/* --- Bottom bar --- */
.v3-footer__bottom {
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
	padding: 25px 0 24px;
	border-top: 1px solid var(--v3-border-white-subtle);
}

.v3-footer__legal {
	display: flex;
	align-items: center;
	gap: var(--v3-space-4);              /* 16px */
}

.v3-footer__legal a {
	color: var(--v3-text-inverse);
	font-size: var(--v3-fs-h5);          /* 20px Regular */
	font-weight: var(--v3-fw-regular);
	line-height: var(--v3-lh-auto);
	text-decoration: none;
	white-space: nowrap;
}

.v3-footer__sep {
	font-size: var(--v3-fs-caption);     /* 14px */
	color: var(--v3-text-inverse);
}

.v3-footer__copy {
	margin: 0;
	font-size: var(--v3-fs-h4);          /* 24px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
}


/* ==========================================================================
   Store glyph (App Store / Google Play)
   The hero and the game-landing pages use the same two paths in different
   colours — Figma exports them twice, once white and once green. Masked and
   tinted with currentColor instead, so one asset each covers both.
   ========================================================================== */

.v3-store-glyph {
	display: block;
	flex: 0 0 auto;
	background: currentColor;
	-webkit-mask: var(--v3-glyph) no-repeat center / contain;
	mask: var(--v3-glyph) no-repeat center / contain;
}

.v3-store-glyph--apple { --v3-glyph: url("/img/v3/hero/apple.svg"); width: 21px; height: 25px; }
.v3-store-glyph--play  { --v3-glyph: url("/img/v3/hero/play.svg");  width: 23px; height: 25px; }

/* The about section uses a larger apple — a genuinely different export, not a
   rescale of the hero one (different path data). */
.v3-store-glyph--apple-lg { --v3-glyph: url("/img/v3/hero/apple-lg.svg"); width: 26.88px; height: 32px; }



/* ==========================================================================
   Navbar — signed-in actions, node 8556:21470
   (Figma calls this variant "Nav bar before sign", which is misleading: by its
   position in the set it is the SIGNED-IN bar — avatar, remaining-games pill
   and a white CTA.)
   RTL: visual order left-to-right is avatar / games / إلعب الآن, so the CTA is
   first in the DOM.
   ========================================================================== */

.v3-navbar__actions--auth { width: 490px; }

.v3-navbar__games {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-2);              /* 8px */
	width: 189px;
	height: 56px;
	padding: var(--v3-space-3);
	border: 1px solid var(--v3-border-white);
	border-radius: var(--v3-radius-pill);
	background: transparent;
	box-shadow: 0 2px 3px 0 rgba(0, 0, 0, .25);
	color: var(--v3-orange-050);         /* Text/Orange/Primary-Subtle #fef2ec */
	font-family: var(--v3-font);
	font-size: var(--v3-fs-title);       /* 18px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	text-decoration: none;
	cursor: pointer;                     /* a button, so a pointer is not implied */
}

/* Kept even though the badge is a button now: if it ever goes back to being a
   link, MDB's a:hover would turn it blue without this. */
.v3-navbar__games:link, .v3-navbar__games:visited, .v3-navbar__games:hover,
.v3-navbar__games:focus, .v3-navbar__games:active {
	color: var(--v3-orange-050);
	text-decoration: none;
}

.v3-navbar__games:hover { background: rgba(255, 255, 255, .12); }

/* Masked so the cup takes the pill's colour rather than shipping a tinted copy. */
.v3-navbar__games i {
	display: block;
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	background: currentColor;
	-webkit-mask: url("/img/v3/cup.svg") no-repeat center / contain;
	mask: url("/img/v3/cup.svg") no-repeat center / contain;
}

/* On a وصلها page the pill counts وصلها's currency, so it does not wear the
   trivia cup — the same swap .v3-appbar__cup--letter makes in the app bar.
   The hexagon is the game's mark everywhere else: the board, the plan cards'
   tiles, app/plans.ejs's artwork. Only the image changes; the shorthand above
   still supplies no-repeat, center and contain. */
.v3-navbar__games--letter i {
	-webkit-mask-image: url("/img/v3/pricing/hex.svg");
	mask-image: url("/img/v3/pricing/hex.svg");
}

/* Figma draws this at 72 — the full height of the 72px nav row — which reads
   oversized next to the 56px pill and CTA. Reduced to 56 so the three line up.
   Deliberate deviation from the design. */
.v3-navbar__avatar {
	flex: 0 0 auto;
	width: 56px;
	height: 56px;
	border: 3px solid var(--v3-border-white);
	border-radius: 50%;
	object-fit: cover;
	background: var(--v3-bg-surface);
}


/* ==========================================================================
   Navbar — profile dropdown, node 8556:21609
   White card anchored to the avatar's left edge. Toggled by a checkbox + label
   like the mobile sheet, so it needs no JS and works in the preview.

   NOTE: Figma's panel also carries a light/dark "نمط العرض" toggle. v3 ships a
   single theme, so it is dropped; its divider is kept above the logout row so
   the separation still reads.
   ========================================================================== */

.v3-navbar__profile {
	position: relative;
	flex: 0 0 auto;
}

.v3-navbar__profile-state { position: absolute; opacity: 0; pointer-events: none; }

.v3-navbar__avatar-btn {
	display: block;
	line-height: 0;
	cursor: pointer;
}

.v3-navbar__dropdown {
	position: absolute;
	top: calc(100% + 6px);
	left: 0;                             /* Figma aligns it to the avatar's left edge */
	z-index: 30;
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-2);              /* 8px */
	width: 212px;
	padding: var(--v3-space-3) 14px;
	border-radius: var(--v3-radius-lg);  /* 24 */
	background: var(--v3-bg-surface);
	box-shadow: 0 4px 16px 0 rgba(0, 0, 0, .25);

	opacity: 0;
	visibility: hidden;
	transform: translateY(-8px) scale(.985);
	transform-origin: top left;
	transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}

.v3-navbar__profile-state:checked ~ .v3-navbar__dropdown {
	opacity: 1;
	visibility: visible;
	transform: none;
	transition: opacity .16s ease, transform .16s ease, visibility 0s;
}

/* Click-away target, behind the panel but above the page. */
.v3-navbar__profile-scrim {
	position: fixed;
	inset: 0;
	z-index: 29;
	display: none;
	cursor: default;
}

.v3-navbar__profile-state:checked ~ .v3-navbar__profile-scrim { display: block; }

/* RTL: icon first in the DOM so it lands on the right, label fills the rest. */
.v3-navbar__menuitem {
	display: flex;
	align-items: center;
	gap: 10px;
	height: 44px;
	padding: 10px 6px;
	border-radius: 10px;
	color: var(--v3-text-primary);       /* #04372a */
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);        /* 16px Medium */
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
	text-decoration: none;
	transition: background .14s ease;
}

.v3-navbar__menuitem span { flex: 1 1 auto; min-width: 0; text-align: start; }

/* Two icon sources in one menu: Figma supplies glyphs for four items, and the
   rest (تحديات + the admin block) keep v2's Font Awesome icons, which Figma
   never drew. Both render at 24px so the column stays aligned. */
.v3-navbar__menuitem .v3-ico {
	display: block;
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	background: currentColor;
	-webkit-mask: var(--v3-glyph) no-repeat center / contain;
	mask: var(--v3-glyph) no-repeat center / contain;
}

.v3-navbar__menuitem .v3-ico--fa {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: none;
	-webkit-mask: none;
	mask: none;
	font-size: 20px;
	line-height: 1;
}

/* DERIVED: Figma defines no hover for the menu rows. */
.v3-navbar__menuitem:hover,
.v3-navbar__menuitem:focus-visible { background: rgba(4, 55, 42, .06); }

.v3-navbar__menuitem:link, .v3-navbar__menuitem:visited,
.v3-navbar__menuitem:focus, .v3-navbar__menuitem:active {
	color: var(--v3-text-primary);
	text-decoration: none;
}

.v3-navbar__menuitem--danger,
.v3-navbar__menuitem--danger:link, .v3-navbar__menuitem--danger:visited,
.v3-navbar__menuitem--danger:hover, .v3-navbar__menuitem--danger:focus,
.v3-navbar__menuitem--danger:active {
	color: var(--v3-error-700);          /* Text/Error #aa3028 */
}

.v3-navbar__menuitem--danger:hover { background: rgba(170, 48, 40, .07); }

/* The rule Figma draws above the display-mode block; kept above logout. */
.v3-navbar__menusep {
	margin-top: var(--v3-space-1);
	padding-top: var(--v3-space-3);
	border-top: 1px solid var(--v3-border-dark-subtle);
}

/* ==========================================================================
   Link-state guard
   MDB ships `a:hover{color:#0e52c1}` — specificity (0,1,1), which OUTRANKS a
   bare class selector (0,1,0) no matter which file loads last. So any anchor
   styled by a single v3 class turns Bootstrap blue on hover unless its colour
   is restated with a pseudo-class. Selectors below are (0,2,0) and win.
   Rules that target a descendant anchor (e.g. `.v3-footer__links a`) are
   already (0,1,1) and win on source order, so they are not repeated here.
   ========================================================================== */

.v3-btn:link, .v3-btn:visited, .v3-btn:hover, .v3-btn:focus, .v3-btn:active,
.v3-btn--green:link, .v3-btn--green:visited, .v3-btn--green:hover, .v3-btn--green:focus, .v3-btn--green:active,
.v3-btn--on-brand:link, .v3-btn--on-brand:visited, .v3-btn--on-brand:hover, .v3-btn--on-brand:focus, .v3-btn--on-brand:active,
.v3-navbar__link:link, .v3-navbar__link:visited, .v3-navbar__link:hover, .v3-navbar__link:focus, .v3-navbar__link:active,
.v3-footer__social:link, .v3-footer__social:visited, .v3-footer__social:hover, .v3-footer__social:focus, .v3-footer__social:active,
.v3-footer__store:link, .v3-footer__store:visited, .v3-footer__store:hover, .v3-footer__store:focus, .v3-footer__store:active,
.v3-hero__store:link, .v3-hero__store:visited, .v3-hero__store:hover, .v3-hero__store:focus, .v3-hero__store:active,
.v3-balance__btn:link, .v3-balance__btn:visited, .v3-balance__btn:hover, .v3-balance__btn:focus, .v3-balance__btn:active {
	color: var(--v3-text-inverse);
	text-decoration: none;
}

/* The game landings size the same badge for the cream page, so it carries the
   secondary text colour rather than the inverse one. */
.v3-gstore:link, .v3-gstore:visited, .v3-gstore:hover, .v3-gstore:focus, .v3-gstore:active {
	color: var(--v3-text-secondary);
	text-decoration: none;
}

/* Anchors that take their colour from what is inside them — an image, or a
   child that sets its own. The guard only has to stop the blue and the
   underline, not impose a colour. */
.v3-gcats__card:link, .v3-gcats__card:visited, .v3-gcats__card:hover, .v3-gcats__card:focus, .v3-gcats__card:active,
.v3-ig__card:link, .v3-ig__card:visited, .v3-ig__card:hover, .v3-ig__card:focus, .v3-ig__card:active,
.v3-social-chip:link, .v3-social-chip:visited, .v3-social-chip:hover, .v3-social-chip:focus, .v3-social-chip:active,
.v3-navbar__logo-link:link, .v3-navbar__logo-link:visited, .v3-navbar__logo-link:hover, .v3-navbar__logo-link:focus, .v3-navbar__logo-link:active {
	color: inherit;
	text-decoration: none;
}

/* A segmented pill is usually a <button>, but on /my-games one of the two is a
   link to another page. It carries the control's own colours either way. */
.v3-segmented__item:link, .v3-segmented__item:visited, .v3-segmented__item:hover,
.v3-segmented__item:focus, .v3-segmented__item:active {
	color: var(--v3-text-inverse);
	text-decoration: none;
}

.v3-segmented__item.is-active:link, .v3-segmented__item.is-active:visited,
.v3-segmented__item.is-active:hover, .v3-segmented__item.is-active:focus,
.v3-segmented__item.is-active:active {
	color: var(--v3-text-secondary);
}

/* إستمر on the back of a previous-game card. */
.v3-mg__action:link, .v3-mg__action:visited, .v3-mg__action:hover,
.v3-mg__action:focus, .v3-mg__action:active {
	color: var(--v3-text-inverse);
	text-decoration: none;
}

/* The copy/mailto wrappers in the purchases tables. They colour nothing
   themselves — the chip inside does — so this only has to stop the blue. */
.v3-cell__copy:link, .v3-cell__copy:visited, .v3-cell__copy:hover,
.v3-cell__copy:focus, .v3-cell__copy:active {
	color: inherit;
	text-decoration: none;
}

/* The الإعدادات rows are anchors as often as they are buttons, and they set
   their own colour — including the red one, which must not go blue either. */
.v3-account__row:link, .v3-account__row:visited, .v3-account__row:focus, .v3-account__row:active {
	color: var(--v3-green-900);
	text-decoration: none;
}

.v3-account__row:hover { color: var(--v3-orange-hover); text-decoration: none; }

.v3-account__row--danger:link, .v3-account__row--danger:visited,
.v3-account__row--danger:focus, .v3-account__row--danger:active { color: var(--v3-error-600); }
.v3-account__row--danger:hover { color: var(--v3-error-700); }

.v3-link:link, .v3-link:visited, .v3-link:focus, .v3-link:active {
	color: var(--v3-text-on-brand);
}

.v3-link--accent:link, .v3-link--accent:visited, .v3-link--accent:hover,
.v3-link--accent:focus, .v3-link--accent:active {
	color: var(--v3-text-accent);
}

.v3-btn--ghost:link, .v3-btn--ghost:visited, .v3-btn--ghost:focus, .v3-btn--ghost:active,
.v3-btn--outline:link, .v3-btn--outline:visited, .v3-btn--outline:focus, .v3-btn--outline:active,
.v3-btn--link:link, .v3-btn--link:visited, .v3-btn--link:focus, .v3-btn--link:active {
	color: var(--v3-text-accent);
	text-decoration: none;
}

.v3-btn--ghost:hover,
.v3-btn--outline:hover,
.v3-btn--link:hover {
	color: var(--v3-orange-hover);
	text-decoration: none;
}

.v3-btn:disabled, .v3-btn.is-disabled { color: var(--v3-orange-disabled-fg); }

/* Descendant-anchor rules already outrank a:hover, but Bootstrap also adds an
   underline on hover, so decoration is pinned for those too. */
.v3-footer__links a:hover, .v3-footer__links a:focus,
.v3-footer__legal a:hover, .v3-footer__legal a:focus {
	color: var(--v3-text-inverse);
	text-decoration: none;
}

/* ==========================================================================
   RESPONSIVE — shell
   DERIVED, not from Figma. The Figma file has exactly two designs: the 1440
   web artboards, and a Mobile page that is the in-app (isApp) layout. There is
   no phone-browser design for the marketing site, so everything below is a
   judgement call built from the desktop design's own tokens.

   Breakpoints used across v3:
     1200  desktop -> narrow desktop   (gutters shrink)
      900  -> tablet                   (nav collapses to a burger)
      600  -> phone                    (single column, type steps down)
   ========================================================================== */

/* THE GAME BAR GIVES AT THE DESIGN WIDTH, not at 1200.

   Its two sides are laid out at fixed widths — 490px of actions and a 235px
   turn pill, 725px before the game's name even appears — and those numbers
   were drawn on a 1440 canvas. They only fit a 1440 canvas.

   Releasing them at 1200 left a 240px band where the bar still used its
   design widths inside a viewport narrower than the design. The centred logo
   is absolutely positioned at 50% and takes part in no layout, so nothing
   pushed back: between 1201 and 1399 the actions group ran straight under it,
   overlapping إنهاء اللعبة by up to 63px. A scaled 13" MacBook lands in the
   middle of that band, which is where it was reported from.

   The order they give in matters: the name and the turn are the only things
   on the bar that carry state. */
@media (max-width: 1440px) {
	.v3-navbar--game .v3-navbar__game-actions { width: auto; gap: var(--v3-space-3); }
	.v3-navbar--game .v3-navbar__game-actions > * { flex: 0 1 auto; }
	.v3-navbar--game .v3-navbar__turn { width: auto; }
	.v3-navbar--game .v3-navbar__team { font-size: var(--v3-fs-h5); padding: 10px 12px; }
}

@media (max-width: 1200px) {
	.v3-navbar__inner { padding: 0 40px; gap: 24px; }

	.v3-navbar__link { font-size: var(--v3-fs-h5); padding: 14px 6px; }
	.v3-navbar__actions { width: 340px; }
	.v3-footer__inner { max-width: none; padding: 40px 40px 0; }
	.v3-footer__cols { gap: 40px; }
}

@media (max-width: 900px) {
	/* --- Nav collapses into a sheet under the bar. The bar keeps its fixed
	   height so the wave background is never stretched. DERIVED: Figma has no
	   phone navbar, so this is built from the system's own language — rounded
	   sheet, pill rows, hairline rule, the same buttons. --- */
	:root { --v3-nav-h: 88px; }
	.v3-navbar { padding-top: 12px; }

	/* Stacking while the sheet is open: page < scrim < bar background < bar
	   content (which contains the sheet). Without this the scrim dims the bar
	   and the sheet itself. */
	.v3-navbar::before { z-index: 11; }
	.v3-navbar__inner { height: 60px; padding: 0 20px; gap: 16px; }
	.v3-navbar__logo { width: 116px; height: 41.8px; }
	.v3-navbar__burger { display: flex; }

	/* --- The game bar on a phone. It is LANDSCAPE only — portraitwarning takes
	   the screen otherwise — so the problem is width, not width and height.

	   No burger and no drawer: the bar's four controls are the game, not site
	   navigation, and hiding the score-keeping behind a menu during a round is
	   worse than shrinking it. The centred logo is what goes instead — it is
	   the one element with no function, and at this width it lands on top of
	   the buttons. DERIVED: Figma draws 1440 only. --- */
	.v3-navbar--game { height: 72px; padding-top: 8px; }
	.v3-navbar--game .v3-navbar__inner { height: 56px; padding: 0 16px; gap: var(--v3-space-2); }
	.v3-navbar--game .v3-navbar__logo--center { display: none; }
	.v3-navbar--game .v3-navbar__game-status { gap: var(--v3-space-2); min-width: 0; }
	.v3-navbar--game .v3-navbar__team {
		font-size: var(--v3-fs-body);
		padding: 6px 8px;
		overflow: hidden;
		text-overflow: ellipsis;
	}
	.v3-navbar--game .v3-navbar__game-actions { height: 40px; gap: var(--v3-space-2); }
	.v3-navbar--game .v3-navbar__turn,
	.v3-navbar--game .v3-navbar__pill,
	.v3-navbar--game .v3-btn {
		height: 40px;
		padding: var(--v3-space-2);
		font-size: var(--v3-fs-caption);
	}
	.v3-navbar--game .v3-navbar__turn img,
	.v3-navbar--game .v3-navbar__pill img { width: 18px; height: 18px; }

	/* The drawer is a DESCENDANT of __inner, so it paints above __inner's
	   statically-positioned children no matter what z-index __inner carries.
	   The logo and burger therefore need their own stacking position to stay
	   on top of it — otherwise the drawer hides the bar and its close button. */
	.v3-navbar__logo-link,
	.v3-navbar__burger { position: relative; z-index: 20; }

	/* A full-height drawer rather than a dropdown sheet. Two reasons: the navbar
	   lives inside .v3-hero, which is overflow:hidden, so an absolutely
	   positioned panel gets CLIPPED at the hero's bottom edge — with the profile
	   menu added, the list is now taller than the hero and the lower half was
	   unreachable. And at ~12 rows a panel is the wrong pattern anyway.
	   position:fixed escapes the clip (no ancestor creates a containing block),
	   and overflow-y keeps any list length reachable. It sits BELOW the bar's
	   z-index so the burger stays visible and closes it. */
	.v3-navbar__menu {
		position: fixed;
		inset: 0;
		z-index: 15;
		display: flex;
		flex-direction: column;
		gap: var(--v3-space-4);
		padding: 100px var(--v3-space-5) var(--v3-space-8);
		border: 0;
		border-radius: 0;
		background: var(--v3-bg-green);
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
		overscroll-behavior: contain;

		/* Animated open/close. visibility is delayed on the way out so the
		   fade can finish before the sheet stops receiving pointer events. */
		opacity: 0;
		visibility: hidden;
		transform: translateY(-8px);
		transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
	}

	.v3-navbar__state:checked ~ .v3-navbar__inner .v3-navbar__menu {
		opacity: 1;
		visibility: visible;
		transform: none;
		transition: opacity .18s ease, transform .18s ease, visibility 0s;
	}

	/* The drawer covers the viewport, so no scrim is needed at this width. */
	.v3-navbar__scrim { display: none; }

	.v3-navbar__scrim--unused {
		position: fixed;
		inset: 0;
		z-index: 10;
		display: block;
		background: rgba(4, 55, 42, .45);
		opacity: 0;
		visibility: hidden;
		transition: opacity .18s ease, visibility 0s linear .18s;
		cursor: default;
	}

	.v3-navbar__state:checked ~ .v3-navbar__scrim {
		opacity: 1;
		visibility: visible;
		transition: opacity .18s ease, visibility 0s;
	}

	.v3-navbar__links {
		flex-direction: column;
		align-items: stretch;
		gap: var(--v3-space-1);
		width: 100%;
	}

	.v3-navbar__link {
		justify-content: flex-start;
		padding: var(--v3-space-3) var(--v3-space-4);
		border-bottom: 0;
		border-radius: var(--v3-radius-md);
		font-size: var(--v3-fs-h5);
		transition: background .15s ease;
	}

	.v3-navbar__link.is-active {
		background: rgba(255, 255, 255, .14);
		color: var(--v3-text-inverse);
	}

	.v3-navbar__link:hover,
	.v3-navbar__link:focus-visible {
		background: rgba(255, 255, 255, .09);
		border-bottom-color: transparent;
	}

	/* Hairline rule between navigation and the actions, as in the footer. */
	.v3-navbar__actions {
		width: 100%;
		margin: 0;
		gap: var(--v3-space-3);
		flex-direction: column;
		padding-top: var(--v3-space-4);
		border-top: 1px solid var(--v3-border-white-subtle);
	}

	.v3-navbar__actions .v3-btn { width: 100%; flex: 0 0 auto; }
	.v3-navbar__actions--auth { width: 100%; }
	.v3-navbar__games { width: 100%; }
	.v3-navbar__avatar { width: 48px; height: 48px; border-width: 2px; }

	/* In the sheet there is nothing to pop over, so the profile menu is shown
	   inline — and styled as sheet rows rather than a white card floating
	   inside a green panel. The avatar is dropped here: it is a trigger on
	   desktop and just decoration once the menu is already open. */
	.v3-navbar__profile { width: 100%; }
	.v3-navbar__avatar-btn { display: none; }
	.v3-navbar__profile-scrim { display: none !important; }

	.v3-navbar__dropdown,
	.v3-navbar__profile-state:checked ~ .v3-navbar__dropdown {
		position: static;
		width: 100%;
		padding: 0;
		gap: var(--v3-space-1);
		border-radius: 0;
		background: transparent;
		box-shadow: none;
		opacity: 1;
		visibility: visible;
		transform: none;
	}

	.v3-navbar__menuitem,
	.v3-navbar__menuitem:link, .v3-navbar__menuitem:visited,
	.v3-navbar__menuitem:focus, .v3-navbar__menuitem:active {
		padding: var(--v3-space-3) var(--v3-space-4);
		border-radius: var(--v3-radius-md);
		color: var(--v3-text-inverse);
		font-size: var(--v3-fs-h5);
	}

	.v3-navbar__menuitem:hover, .v3-navbar__menuitem:focus-visible { background: rgba(255, 255, 255, .09); }

	/* #aa3028 is unreadable on the dark-green sheet; the lighter error tone is. */
	.v3-navbar__menuitem--danger,
	.v3-navbar__menuitem--danger:link, .v3-navbar__menuitem--danger:visited,
	.v3-navbar__menuitem--danger:hover, .v3-navbar__menuitem--danger:focus,
	.v3-navbar__menuitem--danger:active { color: var(--v3-error-500); }

	.v3-navbar__menusep { border-top-color: var(--v3-border-white-subtle); }

	/* Burger turns into a close mark while the sheet is open. */
	.v3-navbar__burger span { transition: transform .18s ease, opacity .18s ease; }
	.v3-navbar__state:checked ~ .v3-navbar__inner .v3-navbar__burger span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
	.v3-navbar__state:checked ~ .v3-navbar__inner .v3-navbar__burger span:nth-child(2) { opacity: 0; }
	.v3-navbar__state:checked ~ .v3-navbar__inner .v3-navbar__burger span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

	/* --- Footer stacks --- */
	.v3-footer__top { flex-direction: column; align-items: center; gap: var(--v3-space-8); }
	.v3-footer__brand { align-items: center; text-align: center; }
	.v3-footer__tagline { text-align: center; font-size: var(--v3-fs-h5); }
	.v3-footer__cols { width: 100%; justify-content: center; gap: var(--v3-space-8); }
	.v3-footer__bottom { flex-direction: column-reverse; gap: var(--v3-space-4); text-align: center; }
	.v3-footer__copy { font-size: var(--v3-fs-body); white-space: normal; }
	.v3-footer__heading { font-size: var(--v3-fs-h5); }
	.v3-footer__links a { font-size: var(--v3-fs-h5); line-height: 1.6; }
	.v3-footer__legal a { font-size: var(--v3-fs-body); }

	/* --- In-game bar: the centred logo would collide with the side controls --- */
	.v3-navbar--game .v3-navbar__inner { flex-wrap: wrap; height: auto; gap: var(--v3-space-2); }
	.v3-navbar__logo--center { position: static; transform: none; width: 132px; height: 47.8px; }
	.v3-navbar__game-actions { width: auto; height: auto; gap: var(--v3-space-2); }
	.v3-navbar__turn { width: auto; min-width: 0; }
}

@media (max-width: 600px) {
	:root { --v3-nav-h: 76px; }
	.v3-navbar { padding-top: 10px; }
	.v3-navbar__inner { height: 52px; padding: 0 16px; }
	.v3-navbar__menu { padding-top: 88px; }   /* bar is 76 here, not 88 */
	.v3-navbar__logo { width: 96px; height: 34.6px; }

	.v3-footer__inner { padding: 32px 20px 0; gap: var(--v3-space-7); }
	.v3-footer__cols { flex-direction: column; align-items: center; gap: var(--v3-space-6); }
	.v3-footer__col { width: 100%; align-items: center; }
	.v3-footer__heading { text-align: center; }
	.v3-footer__links { align-items: center; }
	.v3-footer__links a { text-align: center; }
	.v3-footer__stores { flex-wrap: wrap; justify-content: center; height: auto; }
	.v3-footer__legal { flex-wrap: wrap; justify-content: center; }

	/* Buttons: the 56px/24px desktop size is too heavy on a phone. */
	.v3-btn { height: var(--v3-btn-h-md); font-size: var(--v3-fs-title); }
	.v3-btn--md { height: var(--v3-btn-h-sm); font-size: var(--v3-fs-body); }

	.v3-faq { padding: var(--v3-space-5); border-radius: var(--v3-radius-lg); gap: var(--v3-space-4); }
	.v3-faq__body { font-size: var(--v3-fs-h5); gap: var(--v3-space-3); }
	.v3-faq__toggle { width: 40px; height: 40px; }
	.v3-faq__toggle img { width: 28px; height: 28px; }
	.v3-segmented { height: 56px; }
	.v3-segmented__item { font-size: var(--v3-fs-body); }
}

/* ==========================================================================
   FAQ — collapsed variant, node 7859:6619
   The closed card is NOT just the open one with its answer hidden: it uses a
   different border colour (Border/Green-Disable) and a larger radius
   (80 vs 60), and swaps the chevron for arrow-down.
   ========================================================================== */

.v3-faq.is-collapsed {
	box-shadow: inset 0 0 0 1px var(--v3-border-green-off);   /* #8caea5 */
	border-radius: 80px;
}

/* ==========================================================================
   Reduced motion — drop the nav sheet's transitions.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
	.v3-navbar__menu,
	.v3-navbar__scrim,
	.v3-navbar__burger span,
	.v3-navbar__link { transition: none; }
}

/* ==========================================================================
   Cream button — node 8440:16337
   Cream fill, brand-orange label; used where a primary action sits on the
   orange chrome. Declared AFTER the link-state guard: both are (0,2,0), so on
   equal specificity the later rule wins — placed before it, the guard's white
   `.v3-btn:link` made this label invisible.
   ========================================================================== */

.v3-btn--cream,
.v3-btn--cream:link, .v3-btn--cream:visited,
.v3-btn--cream:hover, .v3-btn--cream:focus, .v3-btn--cream:active {
	background: var(--v3-bg-page);
	color: var(--v3-text-brand);
}

.v3-btn--cream:hover { background: var(--v3-bg-surface); }

/* ==========================================================================
   Modal — chrome from node 8555:12143

   Figma does have a dialog shell, on the الالعاب المتبقية screen: a 775x370
   card at radius 24, a solid green bar across the top, and the close button
   floating on that bar at the physical left. Its backdrop is a grey wash with
   a 9.5px blur, not a dark one. All reproduced here — except the fixed
   775x370, because the plan grid is taller than the two cards Figma puts in
   it, so the dialog sizes to its contents and the body scrolls.

   What is still derived: the plan grid and the payment step inside it. Figma
   has no plan-picker or payment-method dialog — see docs/v3-design-queries.md.
   ========================================================================== */

.v3-modal {
	--v3-modal-in: 240ms;
	--v3-modal-exit: 200ms;              /* modal.js waits this long before hiding */

	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--v3-space-5);
}

.v3-modal[hidden] { display: none; }

.v3-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(127, 127, 127, .2);
	-webkit-backdrop-filter: blur(9.5px);
	backdrop-filter: blur(9.5px);
	opacity: 0;
	transition: opacity var(--v3-modal-exit) ease;
}

.v3-modal.is-open .v3-modal__backdrop {
	opacity: 1;
	transition-duration: var(--v3-modal-in);
}

.v3-modal__dialog {
	position: relative;
	display: flex;
	flex-direction: column;
	width: min(1040px, 100%);
	min-width: 0;                        /* or the content's min-content width
	                                        wins over the 100% above */
	max-height: calc(100vh - 48px);
	border-radius: 24px;
	background: var(--v3-bg-page);
	box-shadow: .683px 8.201px 13.668px 0 rgba(0, 0, 0, .25);
	overflow: hidden;                    /* the bar is flush to the top corners */

	/* Rises and settles, the way the MDB dialogs it replaces did. */
	opacity: 0;
	transform: translateY(16px) scale(.97);
	transition: opacity var(--v3-modal-exit) ease,
	            transform var(--v3-modal-exit) cubic-bezier(.4, 0, .6, 1);
}

.v3-modal.is-open .v3-modal__dialog {
	opacity: 1;
	transform: none;
	transition-duration: var(--v3-modal-in);
	transition-timing-function: ease, cubic-bezier(.16, 1, .3, 1);
}

/* A dialog handing over to another sits behind it while both are on screen, so
   the incoming one reads as the thing that moved. */
.v3-modal:not(.is-open) { pointer-events: none; z-index: 999; }

@media (prefers-reduced-motion: reduce) {
	.v3-modal__backdrop,
	.v3-modal__dialog { transition: none; }
	.v3-modal__dialog { transform: none; }
}

/* Set on <html> while the dialog is up, so the page behind cannot scroll. */
.v3-modal-open { overflow: hidden; }

/* The bar spans the dialog with the title at the RTL start; the close button
   floats over it rather than sitting in the flow. */
.v3-modal__head {
	position: relative;
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: var(--v3-space-4);
	height: 76.543px;
	padding: 19.136px 68.342px;
	background: var(--v3-bg-green);      /* #064e3b */
}

.v3-modal__title {
	margin: 0;
	color: var(--v3-white);
	font-size: var(--v3-fs-h5);          /* Figma types 18; 20 is the near step */
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
}

/* Figma pins the dialog to 370px tall. The plan grid needs more, so the body
   scrolls rather than the whole dialog — which keeps the bar in place. */
.v3-modal__body {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-6);
	padding: var(--v3-space-7);
	overflow-y: auto;
	overscroll-behavior: contain;
}

/* Cream disc on the green bar, physical left — node 8555:12206. */
.v3-modal__close {
	position: absolute;
	left: 19px;
	top: 19px;
	width: 40px;
	height: 40px;
	border: 0;
	border-radius: 32px;
	background: var(--v3-bg-page);
	cursor: pointer;
	transition: background-color .15s ease;
}

.v3-modal__close::before {
	content: "";
	position: absolute;
	inset: 4px;
	background: var(--v3-green-icon);    /* #054736, the stroke Figma uses */
	-webkit-mask: url("/img/v3/cancel.svg") no-repeat center / contain;
	mask: url("/img/v3/cancel.svg") no-repeat center / contain;
}

.v3-modal__close:hover { background: var(--v3-orange-050); }

.v3-modal__step {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-6);
}

.v3-modal__step[hidden] { display: none; }

.v3-modal__tabs {
	align-self: center;
	height: 52px;                        /* 72 x 52/72 — see below */
	padding: 4px 9px;
	border-radius: 29px;
}

.v3-modal__tabs .v3-segmented__item {
	flex: 0 0 auto;
	padding: 7px var(--v3-space-5);
	border-radius: 23px;
	font-size: var(--v3-fs-title);       /* 18px, down from 20 */
}

.v3-modal__tabs::after {
	top: 4.31px;
	left: 9.75px;
	width: 9.028px;
	height: 5.8px;
}

.v3-modal__grid[hidden] { display: none; }

.v3-modal__back {
	position: relative;
	align-self: flex-start;              /* right, in RTL */
	width: 44px;
	height: 44px;
	border: 1px solid var(--v3-green-300);
	border-radius: 50%;
	background: var(--v3-white);
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease;
}

.v3-modal__back::before {
	content: "";
	position: absolute;
	inset: 11px;
	background: var(--v3-green-800);
	-webkit-mask: url("/img/v3/arrow-left.svg") no-repeat center / contain;
	mask: url("/img/v3/arrow-left.svg") no-repeat center / contain;
	transform: scaleX(-1);               /* RTL: back points to the right */
}

.v3-modal__back:hover {
	border-color: var(--v3-orange-500);
	background: var(--v3-orange-050);
}

.v3-modal__back:hover::before { background: var(--v3-orange-500); }

.v3-modal__summary {
	margin: 0;
	color: var(--v3-text-secondary);
	font-size: var(--v3-fs-h5);
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	text-align: start;
}

/* Outlined coupon pill — node 8050:12899 on the payment dialog and I8140:6256
   on the checkout page. Same component in both. */
.v3-coupon-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-1);
	height: 56px;
	padding: 12px;
	border: 1px solid var(--v3-border-orange);
	border-radius: 999px;
	background: none;
	box-shadow: 0 2px 3px 0 rgba(0, 0, 0, .25);
	color: var(--v3-orange-500);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-title, 18px);
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	cursor: pointer;
	transition: background-color .15s ease;
}

.v3-coupon-btn:hover { background: var(--v3-orange-050); }

/* --------------------------------------------------------------------------
   Payment methods
   -------------------------------------------------------------------------- */

.v3-pay {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-3);
}

.v3-pay__option {
	display: flex;
	align-items: center;
	gap: var(--v3-space-4);
	width: 100%;
	padding: 15px 16px;
	border: 1px solid var(--v3-bg-green);
	border-radius: 16px;
	background: none;
	font-family: var(--v3-font);
	text-align: start;
	cursor: pointer;
	transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}

.v3-pay__option[hidden] { display: none; }
.v3-pay__option:hover { border-color: var(--v3-orange-200); }

/* DERIVED: Figma draws all four rows unselected, so the selected treatment is
   ours — the same orange the rest of v3 uses for a chosen thing. */
.v3-pay__option.is-active {
	border-color: var(--v3-orange-500);
	background: var(--v3-orange-050);
}

.v3-pay__logo {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 61.412px;
	height: 32px;
}

.v3-pay__logo img { max-width: 100%; max-height: 100%; object-fit: contain; }

.v3-pay__text {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.v3-pay__text {
	gap: var(--v3-space-2);
	text-align: start;
}

.v3-pay__text strong {
	color: var(--v3-green-900);
	font-size: var(--v3-fs-h5);          /* 20px Medium */
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
}

.v3-pay__text small {
	color: var(--v3-green-900);
	font-size: var(--v3-fs-body);        /* 16px Regular */
	font-weight: var(--v3-fw-regular);
	line-height: var(--v3-lh-auto);
}

.v3-pay__mark {
	flex: 0 0 auto;
	position: relative;
	width: 20px;
	height: 20px;
	border: 1.5px solid var(--v3-green-500);
	border-radius: 50%;
}

.v3-pay__option.is-active .v3-pay__mark { border-color: var(--v3-orange-500); }

.v3-pay__option.is-active .v3-pay__mark::after {
	content: "";
	position: absolute;
	inset: 3px;
	border-radius: 50%;
	background: var(--v3-orange-500);
}

/* --------------------------------------------------------------------------
   Coupon, errors, submit
   -------------------------------------------------------------------------- */

.v3-modal__coupon-field { width: min(455px, 100%); align-self: flex-end; }
.v3-modal__coupon-field[hidden] { display: none; }

/* Back at the RTL start, the coupon and confirm paired at the other end — the
   pairing is Figma's (8050:12922), the back button is where it belongs now
   that it is an icon rather than a sentence. */
.v3-modal__actions {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--v3-space-4);
}

.v3-modal__actions-main {
	display: flex;
	align-items: center;
	gap: var(--v3-space-5);              /* 24px */
	width: 455px;
	max-width: 100%;
}

.v3-modal__actions-main > * { flex: 1 0 0; min-width: 0; }

.v3-modal__error {
	margin: 0;
	color: var(--v3-error-600);
	font-size: var(--v3-fs-body);
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
	text-align: start;
}

.v3-modal__error[hidden] { display: none; }

.v3-modal__submit { height: 56px; font-size: var(--v3-fs-title, 18px); }

@media (max-width: 900px) {
	.v3-modal { padding: var(--v3-space-3); }
	.v3-modal__dialog { max-height: calc(100vh - 24px); }
	.v3-modal__head { height: 64px; padding: 12px 20px 12px 64px; }
	.v3-modal__body { gap: var(--v3-space-5); padding: var(--v3-space-5); }
	.v3-modal__title { font-size: var(--v3-fs-body); }
	.v3-modal__close { left: 12px; top: 12px; width: 34px; height: 34px; }
}

@media (max-width: 600px) {
	.v3-pay__option { gap: var(--v3-space-3); padding: 12px 14px; }
	.v3-pay__logo { width: 48px; height: 26px; }
	.v3-pay__text strong { font-size: var(--v3-fs-body); }
	.v3-pay__text small { font-size: var(--v3-fs-caption); }

	/* The three buttons stop fitting one row well before this. */
	.v3-modal__actions { flex-wrap: wrap; }
	.v3-modal__actions-main { width: 100%; order: 2; }
	.v3-coupon-btn,
	.v3-modal__submit { height: var(--v3-btn-h-sm); font-size: var(--v3-fs-body); }
}

/* ==========================================================================
   رصيدك — node 8555:12143

   The dialog the games-count badge opens. Shares the modal chrome; only the
   two game cards are new. Figma pins the dialog to 775x370 with two 300x219
   cards 24 apart — kept, except that the dialog is allowed to shrink on a
   phone rather than overflowing.
   ========================================================================== */

.v3-modal--balance .v3-modal__dialog { width: min(775px, 100%); }

/* Node 8555:12148 — the cards sit in 624 of a 775 dialog, so the body is padded
   76 rather than the 40 the plans grid uses. */
.v3-modal--balance .v3-modal__body { padding: 25px 76px 49px; }

/* The head carries a mark beside its title here (node 8555:12147). */
.v3-modal__head-icon {
	flex: 0 0 auto;
	width: 32px;
	height: 32px;
	background: var(--v3-white);
	/* Node 8555:12147 is the brand mark, not the cup the navbar badge carries. */
	-webkit-mask: url("/img/v3/logo-mark.png") no-repeat center / contain;
	mask: url("/img/v3/logo-mark.png") no-repeat center / contain;
}

.v3-balance {
	display: flex;
	align-items: stretch;
	justify-content: center;
	gap: var(--v3-space-5);              /* 24px */
}

.v3-balance__card {
	position: relative;
	flex: 1 1 300px;
	max-width: 300px;
	min-height: 219px;
	padding: 30px 28px;                  /* node 8555:12196 — 244x159 in 300x219 */
	border-radius: 16px;
	background: var(--v3-bg-green);      /* #064e3b */
	overflow: hidden;
}

/* Node 8555:12193 — the small arc from the segmented track, at the card's LEFT
   and mirrored. The plan cards use the larger one on the right, so the size has
   to change too, not just the side. */
.v3-balance__card .v3-plan__shine {
	right: auto;
	left: 17px;                          /* leaf 18.5 less the 1.5 overhang */
	top: 5.97px;
	width: 12.5px;
	height: 8.03px;
	background-image: url("/img/v3/switch-shine.svg");
	transform: scaleX(-1);
}

/* Each card carries its game's motif. Both are barely there — measured off the
   Figma render, the motif pixels are white at ~4% over the card's #064e3b — but
   they are large, and they are what keeps the card from reading as a flat
   rectangle. Do not add an opacity on top of these: honeycomb.svg already
   carries fill-opacity .035, which IS the 4%. */
.v3-balance__deco {
	position: absolute;
	pointer-events: none;
}

/* Measured off node 8555:12143: hexagons 72 wide and 61 tall with a 3px gap,
   flat-top, no rotation. Figma draws a finite block of them whose corner cuts
   the card on the line y = 154.5 - 0.593x — bare at the top-left, full by the
   bottom-right. The mask is that line, softened: a hard edge would slice
   hexagons in half, which only looks right when the block is whole hexes. */
.v3-balance__card--letter .v3-balance__deco {
	inset: 0;
	background: url("/img/v3/pricing/honeycomb.svg") repeat;
	background-size: 108px 64px;
	-webkit-mask: linear-gradient(149.3deg, transparent 37%, #000 43%);
	mask: linear-gradient(149.3deg, transparent 37%, #000 43%);
}

/* Node 8555:12195 — the two-card mark, 214px square, rotated about its own
   top-left corner and mostly hanging off the card's right edge. Angle and
   origin were fitted against the Figma render (IoU .72); the card's own
   overflow does the clipping, so this survives the card being resized. */
.v3-balance__card--trivia .v3-balance__deco {
	left: calc(100% + 18px);             /* 318 on the 300px card, and it tracks
	                                        the card once it stretches on phones */
	top: 46px;
	width: 214px;
	height: 214px;
	background: url("/img/v3/game/cards.webp") no-repeat center / contain;
	opacity: .04;                        /* measured: white at ~4% over #064e3b */
	transform: rotate(66.5deg);
	transform-origin: 0 0;
}

.v3-balance__inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: 42px;
	min-height: 159px;
}

/* Grows to fill, which pins the buttons to the bottom of the card instead of
   leaving a gap under them — node 8555:12197 is flex-[1_0_0]. */
.v3-balance__count {
	flex: 1 0 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 13.123px;
	text-align: center;
}

.v3-balance__title {
	color: var(--v3-white);
	font-size: var(--v3-fs-h5);          /* 20px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
}

.v3-balance__number {
	color: var(--v3-white);
	font-size: var(--v3-fs-h4);          /* 24px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
}

.v3-balance__actions {
	display: flex;
	align-items: stretch;
	gap: 13px;
}

/* Node 8555:12202 — a 36px orange pill with a leading glyph. Small enough that
   the shared button's shine arcs would crowd it, so it is its own thing. */
.v3-balance__btn {
	flex: 1 0 0;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-1);
	height: 36px;
	padding: 12px;
	border: 0;
	border-radius: 999px;
	background: var(--v3-bg-brand);
	box-shadow: 0 2px 1.5px 0 rgba(0, 0, 0, .25);
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);     /* 14px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	text-decoration: none;
	cursor: pointer;
	position: relative;                  /* the arcs below resolve against this */
	overflow: hidden;                    /* and stay inside the pill */
	transition: background-color .15s ease;
}

/* Shine arcs, as .v3-btn — every offset and size is the .v3-btn value times
   36/56, because Figma's instance here is the 36px button (8555:12191). */
.v3-balance__btn::before,
.v3-balance__btn::after {
	content: "";
	position: absolute;
	pointer-events: none;
	background-repeat: no-repeat;
	background-size: 100% 100%;
}

.v3-balance__btn::after {
	top: 3.18px;
	right: 3.86px;
	width: 19.287px;
	height: 15.494px;
	background-image: url("/img/v3/btn-shine-right.svg");
}

.v3-balance__btn::before {
	top: 4.63px;
	left: 7.348px;
	width: 8.446px;
	height: 6.785px;
	background-image: url("/img/v3/btn-shine-left.svg");
	transform: scaleX(-1);
}

.v3-balance__btn:hover { background: var(--v3-orange-hover); }

.v3-balance__ico {
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	background: currentColor;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

/* RTL: the arrow points to the right. */
.v3-balance__ico--play {
	-webkit-mask-image: url("/img/v3/arrow-left.svg");
	mask-image: url("/img/v3/arrow-left.svg");
	transform: scaleX(-1);
}

.v3-balance__ico--cart {
	-webkit-mask-image: url("/img/v3/cart.svg");
	mask-image: url("/img/v3/cart.svg");
}

@media (max-width: 600px) {
	.v3-modal--balance .v3-modal__body { padding: var(--v3-space-5); }
	.v3-balance { flex-direction: column; align-items: stretch; }
	/* flex-basis is the main axis, and the main axis is now the height. */
	.v3-balance__card { flex: 0 0 auto; max-width: none; min-height: 0; }
	.v3-balance__inner { gap: var(--v3-space-5); min-height: 0; }
	.v3-modal--balance .v3-modal__head-icon { width: 24px; height: 24px; }
}


/* ==========================================================================
   Plan card — nodes 8440:16406 (trivia) / 8440:16773 (وصلها)

   Lives here, not with the game landing, because the plans dialog renders it
   on EVERY page. While these rules were page-scoped the modal's cards were
   unstyled anywhere but the two landings, and the balance card lost its
   corner shine with them.
   ========================================================================== */

.v3-plans__grid {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	justify-content: center;
}

/* --------------------------------------------------------------------------
   The card
   -------------------------------------------------------------------------- */

.v3-plan {
	--v3-plan-h: 200px;
	--v3-plan-art: 127.778px;
	--v3-plan-gap: 22.25px;              /* art panel to content */

	position: relative;
	display: flex;                       /* RTL: the body is the first child, so
	                                        it lands on the right and the art
	                                        panel on the left, as Figma has it */
	width: 380px;
	height: auto;
	min-height: var(--v3-plan-h);        /* grows if a plan carries bonus games */
	border-radius: 28px;
	background: linear-gradient(-60.16deg, var(--v3-green-850) .11%, var(--v3-green-800) 95.46%);
	box-shadow: 0 1.132px 11.323px 0 rgba(0, 0, 0, .25);
	overflow: hidden;
	text-decoration: none;
}

/* Vector 23 — the shine arc the buttons carry, here in the card corner. The
   asset overflows its Figma leaf box by half the stroke width on every side
   (4.303 / 2), which is what these offsets subtract. */
.v3-plan__shine {
	position: absolute;
	top: 4.64px;
	right: 10.54px;
	width: 16.7592px;
	height: 11.0951px;
	background: url("/img/v3/pricing/card-shine.svg") no-repeat center / 100% 100%;
	pointer-events: none;
	z-index: 2;
}

.v3-plan__art {
	position: relative;
	flex: 0 0 var(--v3-plan-art);
	align-self: stretch;
	background: rgba(3, 43, 32, .65);
	border-start-end-radius: 20px;       /* only the inner corners are rounded;
	                                        the outer pair is clipped by the card */
	border-end-end-radius: 26.667px;
}

.v3-plan__medal {
	position: absolute;
	left: 50%;
	top: 14.44px;
	width: 131px;
	height: 126.5px;
	transform: translateX(-50%);
}

.v3-plan__badge {
	position: absolute;
	left: 50%;
	top: 152.22px;
	transform: translateX(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	/* THE BADGE IS CENTRED ON A 128px ART COLUMN AND HAS TO FIT IT.

	   At Figma's padding the two longest labels — «اختيار الجمعات» and
	   «وفّر 40 ر.س», both with an icon — measured 133px, so they hung 2.5px off
	   each side of a 128px art. The art sits at the card's outer edge, so that
	   overhang left the card entirely on one side.

	   The horizontal padding and the gap carry the difference rather than the
	   type: shrinking the text would have made the shortest badges illegible to
	   solve a problem only the longest two have. */
	gap: 3.5px;
	padding: 6.667px 7.5px;
	border: .556px solid var(--v3-green-800);
	border-radius: 8.889px;
	background: rgba(0, 0, 0, .1);
	box-shadow: inset 1.111px 0 4.444px 0 rgba(255, 255, 255, .15);
	color: var(--v3-gold-400);
	font-size: var(--v3-fs-caption);     /* 14px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
}

.v3-plan__badge img { width: 22.222px; height: 22.222px; }

/* The "وفر 10%" badge inverts: a light wash instead of a dark one. */
.v3-plan__badge--light {
	background: rgba(255, 255, 255, .1);
	color: var(--v3-white);
}

.v3-plan__badge--orange { color: var(--v3-orange-300); }

/* --------------------------------------------------------------------------
   Card body
   -------------------------------------------------------------------------- */

.v3-plan__body {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 7.778px;
	padding-block: 15.85px 15.56px;
	padding-inline: 16.64px var(--v3-plan-gap);
}

.v3-plan__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--v3-space-2);
	padding-bottom: 4.444px;
	border-bottom: 1.111px solid rgba(255, 255, 255, .08);
}

.v3-plan__title {
	display: flex;
	flex-direction: column;
	align-items: center;                 /* Figma centres the tag under the name */
	gap: 8.889px;
	min-width: 0;
	color: var(--v3-green-050);
}

.v3-plan__name {
	font-size: var(--v3-fs-body);        /* 16px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
}

.v3-plan__tag {
	font-size: var(--v3-fs-caption);     /* 14px Regular */
	font-weight: var(--v3-fw-regular);
	line-height: var(--v3-lh-auto);
}

/* A figure and its currency glyph read left-to-right even on an RTL page, the
   same way the store badges do. */
.v3-plan__price {
	direction: ltr;
	display: flex;
	align-items: flex-end;
	gap: 1.111px;
	flex: 0 0 auto;
}

/* 44% up on the 20px Figma draws — 20 to 24 to 28.8, two steps of a fifth. The
   glyph is small, tilted and pale, and at the drawn size it read as a smudge
   beside a 32px figure rather than as a currency mark; one step was not enough
   to fix that. 28.8 stands nearly as tall as the digits it sits beside, which
   is what makes it read as part of the price.

   The width follows the same 0.992 ratio the export has, so it is scaled and
   not stretched. Matched by .v3-appplan__riyal in pages/app-plans.css, which is
   the same glyph on the app screen and takes the same step. */
.v3-plan__riyal {
	width: 28.577px;
	height: 28.8px;
	margin-bottom: 1px;
	transform: rotate(-29.48deg);
}

.v3-plan__amount {
	color: var(--v3-lime-200);
	font-size: var(--v3-fs-h3);          /* 32px Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
}

/* space-between pushes the CTA to the bottom of the body, but Figma always
   leaves a gap under it — 15.85px on the وصلها card (8495:12805) and 15.56 on
   the trivia one (8440:16441), while the gap ABOVE the button varies with how
   many features the plan lists. So the constant is below, not above. */
.v3-plan__main {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--v3-space-3);
	padding-bottom: 15.7px;
}

.v3-plan__features {
	display: flex;
	flex-direction: column;
	gap: 14.444px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* RTL: flex-start is the right edge, which is where the tick sits. */
.v3-plan__feature {
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: 11.111px;
	color: var(--v3-green-050);
	font-size: var(--v3-fs-caption);     /* 14px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
}

.v3-plan__tick {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 22.222px;
	height: 22.222px;
	border-radius: 50%;
	background: var(--v3-green-800);
}

.v3-plan__tick i {
	display: grid;
	place-items: center;
	width: 17.778px;
	height: 17.778px;
	border: .556px solid var(--v3-white);
	border-radius: 50%;
}

.v3-plan__tick i::before {
	content: "";
	width: 8.889px;
	height: 10px;
	background: var(--v3-white);
	-webkit-mask: url("/img/v3/tick.svg") no-repeat center / contain;
	mask: url("/img/v3/tick.svg") no-repeat center / contain;
}

/* The CTA is the standard button at this card's own 40px height. Its shine
   arcs are a flatter glyph than the 56px button's, so they are their own
   assets rather than a scale of the shared pair. */
.v3-plan__cta {
	width: 100%;
	height: 40px;
	font-size: var(--v3-fs-body);        /* 16px */
	box-shadow: 0 2.222px 1.667px rgba(0, 0, 0, .25), inset 0 -2.222px 4.444px 0 rgba(0, 0, 0, .25);
}

.v3-plan__cta::after {
	top: 4.56px;
	right: 9px;
	width: 16.4451px;
	height: 10.8871px;
	background-image: url("/img/v3/pricing/cta-shine-right.svg");
}

.v3-plan__cta::before {
	top: 5.49px;
	left: 8.58px;
	width: 8.38769px;
	height: 6.73814px;
	background-image: url("/img/v3/pricing/cta-shine-left.svg");
	transform: scaleX(-1);               /* Figma mirrors it: -scale-y-100 plus
	                                        rotate-180 comes out as scaleX(-1) */
}

/* --------------------------------------------------------------------------
   وصلها variant — node 8495:12552
   A honeycomb ground across the whole card and orange letter tiles instead of
   the medallion. No badge: the وصلها plans do not carry one.
   -------------------------------------------------------------------------- */

.v3-plan--letter {
	--v3-plan-h: 188px;
	--v3-plan-art: 130px;
	--v3-plan-gap: 20px;
}

.v3-plan--letter::before {
	content: "";
	position: absolute;
	inset: 0;
	background: url("/img/v3/pricing/honeycomb.svg") repeat;
	background-size: 116.6px 66.75px;
	pointer-events: none;
}

.v3-plan--letter .v3-plan__art,
.v3-plan--letter .v3-plan__body { position: relative; z-index: 1; }

.v3-plan__hexes {
	position: absolute;
	inset: 0;
	transform: translateY(-1.5px);       /* Figma sits the art just above centre */

	/* The glow belongs HERE, not on the cells. CSS applies filter before mask,
	   so a drop-shadow on a masked element is drawn and then clipped away by
	   its own mask — which is why the cells had no glow at all. On the parent
	   it lights the cluster as one shape, and the 1.2px seams between cells
	   stay dark, which is what Figma shows.
	   Node 8683:18265 publishes dy .858 and stdDeviation 3.003; a CSS blur
	   radius is twice the deviation. */
	filter: drop-shadow(0 .858px 6.006px rgba(242, 122, 61, .6));
}

/* These cells are POINTY-top — taller than wide — not the flat-top hexagon the
   honeycomb ground uses. Measured off the Figma renders of 8495:12552 (one
   cell) and 8495:12805 (three), against their 130 x 188 art panel:

     one cell    51 x 59, centred at (65, 92)
     three cells 43 x 49.5 each, pitch 46 across and 40 down, same centre

   The pitch is deliberately WIDER than the cell — 3px of the card shows between
   neighbours, and that gap is the border between them. The previous flat-top
   tiles were 56 wide on a 42 pitch, so they overlapped and merged into one
   blob with no cell edges at all. */
.v3-plan__hexes span {
	position: absolute;
	left: 50%;
	top: 50%;
	/* The box has to carry the ASSET's aspect (.8566). An SVG keeps its own
	   preserveAspectRatio inside mask-size, so a box of any other shape
	   letterboxes the hexagon instead of filling — which is what left the cells
	   1.7px narrow and the gaps correspondingly wide. */
	width: 52.2px;
	height: 60.9px;
	margin: -30.45px 0 0 -26.1px;
	background: var(--v3-orange-500);
	-webkit-mask: url("/img/v3/pricing/hex-cell.svg") no-repeat center / 100% 100%;
	mask: url("/img/v3/pricing/hex-cell.svg") no-repeat center / 100% 100%;
}

/* THE BADGE SITS LOWER ON A وصلها CARD, because the honeycomb needs room under
   it. On a trivia card the badge hangs below a medal that stops well short of
   it; the cells reach much further down, so at the shared 152px the badge was
   almost touching them — 2px under the single cell.

   Moving it down rather than shrinking the cells also uses space that was doing
   nothing: the art is 242 tall and everything below 184 was empty. Scoped to
   --letter so the trivia cards keep the position Figma gives them. */
.v3-plan--letter .v3-plan__badge { top: 168px; }

/* RAISED CLEAR OF THE BADGE.

   The cluster centres in the art and the badge is pinned 152px from its top,
   which the single cell clears by 2px. Three cells are half again as tall —
   the bottom one reached 165px — so the badge sat on top of the honeycomb.

   Moving the cluster is the smaller change: the badge's position is shared
   with every trivia card, and the single-cell card is exactly as Figma draws
   it. -21.2 puts the bottom cell's edge at 146, six clear of the badge. */
.v3-plan__hexes--3 { transform: translate(.9px, -21.2px); }

.v3-plan__hexes--3 span {
	width: 45px;
	height: 52.5px;
	margin: -26.25px 0 0 -22.5px;
}

/* Pitch 46.2 across against a 45 cell, so the neighbours are 1.2px apart —
   Figma's cells very nearly touch and the dark seam between them IS the border.
   Anything wider stops reading as a honeycomb and starts reading as three
   separate tiles, which is what the old overlapping flat-top tiles and then the
   3px gap both got wrong, in opposite directions. */
.v3-plan__hexes--3 span:nth-child(1) { transform: translate(-23.1px, -19.95px); }
.v3-plan__hexes--3 span:nth-child(2) { transform: translate(23.1px, -19.95px); }
.v3-plan__hexes--3 span:nth-child(3) { transform: translate(0, 19.95px); }
@media (max-width: 900px) {
	.v3-plan { width: 100%; max-width: 380px; }
}
@media (max-width: 600px) {

	/* Below roughly 360px of card the feature lines stop fitting on one line,
	   so the card grows rather than clipping them. */
	.v3-plan {
		--v3-plan-art: 104px;
		--v3-plan-gap: 14px;
		height: auto;
		min-height: var(--v3-plan-h);
	}
	.v3-plan__medal { width: 104px; height: 100.4px; top: 22px; }
	.v3-plan__badge { padding: 5px 8px; font-size: 12px; top: auto; bottom: 12px; }
	.v3-plan__badge img { width: 18px; height: 18px; }
	/* 0.8 of the desktop cell, which is what the art column itself does
	   (130 -> 104). The ratio is the asset's 0.857 in both cases — see the
	   note on .v3-plan__hexes span; anything else letterboxes the hexagon. */
	.v3-plan__hexes span { width: 41.76px; height: 48.72px; margin: -24.36px 0 0 -20.88px; }
	.v3-plan__hexes--3 span { width: 36px; height: 42px; margin: -21px 0 0 -18px; }
	.v3-plan__hexes--3 span:nth-child(1) { transform: translate(-18.48px, -15.96px); }
	.v3-plan__hexes--3 span:nth-child(2) { transform: translate(18.48px, -15.96px); }
	.v3-plan__hexes--3 span:nth-child(3) { transform: translate(0, 15.96px); }
	.v3-plan__amount { font-size: var(--v3-fs-h4); }
	.v3-plan__feature { align-items: flex-start; }
}
/* ==========================================================================
   Alert / confirm dialog — Figma 8031:11004 (plain), 8031:10970 (countdown),
   8031:10994, 7928:8996 and the rest of the popup set.

   Twelve frames, one component. What varies between them is which slots are
   filled: an icon badge straddling the top edge, a close control, a title, a
   body, and then EITHER a row of buttons OR a countdown ring. Nothing about the
   surface itself changes except its radius and padding, and those change with
   the badge — a badge needs more room above the title.

   It rides on .v3-modal (the backdrop, the rise-and-settle, the scroll lock),
   so only the panel is described here. Built by /js/v3/dialog.js rather than
   included from a layout: the game shell has no footer to include it from, and
   these are opened imperatively.
   ========================================================================== */

.v3-modal--alert .v3-modal__dialog {
	width: min(520px, 100%);
	padding: 44px 16px;
	border-radius: 18px;
	background: var(--v3-bg-page);
	box-shadow: 0 4px 10px 0 rgba(0, 0, 0, .25);
	overflow: visible;                   /* the badge hangs over the top edge */
}

/* With a badge the panel is rounder, and the title has to clear the half of the
   badge that hangs INSIDE it — 8031:10970. Figma buys that room with a sparkle
   in the flow; this is the same 25.31px, as padding, so the sparkles can stay
   decorative and absolute. */
.v3-modal--alert.has-badge .v3-modal__dialog {
	padding: 58px 28px 32px;
	border-radius: 32px;
	margin-top: 52.57px;                 /* and room for the half that hangs out */
}

.v3-dialog {
	--v3-dialog-accent: var(--v3-orange-600);

	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 48px;
	width: 100%;
	min-width: 0;
}

.v3-modal--alert.has-badge .v3-dialog { gap: 20px; }

/* The danger set — 8031:11004 tones the message and the cancel button in error
   colours rather than the brand's. */
.v3-dialog--danger { --v3-dialog-accent: var(--v3-error-700); }

/* ---- the badge -------------------------------------------------------- */

/* Centred on the panel's top edge. The gradient and the inner white highlight
   are Figma's; the icon inside is the game's own PNG at its drawn size. */
.v3-dialog__badge {
	position: absolute;
	top: -52.57px;
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px 20px 20px 24px;
	border-radius: 99px;
	background: linear-gradient(to bottom, var(--v3-orange-500), #d47e53);
	box-shadow: inset 0 7.79px 7.79px 0 rgba(255, 255, 255, .5);
}

.v3-dialog__badge img { display: block; width: auto; height: 64px; object-fit: contain; }

/* ---- the close control ------------------------------------------------ */

/* Physically LEFT, which is where every popup frame puts it — not the inline
   end, because the dialog's own text direction should not move it. */
.v3-dialog__close {
	position: absolute;
	left: 24px;
	top: 24px;
	display: block;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	background: url("/img/v3/cancel.svg") no-repeat center / 100% 100%;
	cursor: pointer;
	opacity: .9;
}

.v3-dialog__close:hover { opacity: 1; }

/* ---- the sparkles ----------------------------------------------------- */

/* Two of them, placed as Figma places them: one against the panel's top right,
   one loose beside the title. Decoration only. */
.v3-dialog__sparkle {
	position: absolute;
	display: block;
	width: 25.31px;
	height: 25.31px;
	pointer-events: none;
}

.v3-dialog__sparkle--a { right: 28px; top: 32px; }
.v3-dialog__sparkle--b { left: 126.57px; top: 85.68px; }

/* ---- the words -------------------------------------------------------- */

.v3-dialog__text {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 27.26px;
	width: 100%;
}

.v3-dialog__title {
	margin: 0;
	width: 100%;
	color: var(--v3-dialog-accent);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h3);          /* 32px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	text-align: center;
}

/* Without a badge the title is the whole message and sits at 24 — 8031:11004. */
.v3-modal--alert:not(.has-badge) .v3-dialog__title { font-size: var(--v3-fs-h4); }

.v3-dialog__body {
	width: 100%;
	color: var(--v3-text-primary);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h4);          /* 24px Regular */
	font-weight: var(--v3-fw-regular);
	line-height: var(--v3-lh-normal);
	text-align: center;
}

.v3-dialog__body p { margin: 0 0 var(--v3-space-2); }
.v3-dialog__body p:last-child { margin-bottom: 0; }

/* ---- the buttons ------------------------------------------------------ */

.v3-dialog__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--v3-space-3);              /* 12px */
	width: 100%;
}

/* EQUAL HALVES UNTIL A LABEL NEEDS MORE.

   `flex: 1 0 0` alone split the row evenly whatever was written on the
   buttons, and عرض الرموز الإحتياطية — the longest label in the app, from
   my-account.js — was clipped mid-word inside a button that had room to spare
   beside an إلغاء.

   The fix for that was `1 1 auto`, which starts each button at its own width
   and shares only what is left over. That divides the SPARE space equally, not
   the row: the difference between two labels survives at every width, and on a
   phone — where there is barely any spare — تسجيل دخول came out half again as
   wide as إلغاء in a pair that should look like a pair.

   So: a zero basis, which splits the row evenly, and a floor of fit-content,
   which lets a button that cannot fit its label take what it needs from the
   other. Short pairs are equal; the long label is still not clipped.

   fit-content and not max-content, because the floor is also the width the
   button claims when the pair wraps to two lines — and max-content on a 390px
   phone would let a long enough label push past the dialog instead of
   wrapping inside it. flex-wrap stays the backstop for a pair that cannot
   share one line. */
.v3-dialog__actions > * { flex: 1 1 0; min-width: fit-content; }

/* AND THE SAME BORDER FOOTPRINT, so "equal" is equal to the pixel. A zero
   flex-basis on a border-box element floors at its border + padding, so the
   outlined cancel started 2px up on the borderless primary and stayed 2px
   wider at every width. A transparent border costs the primary nothing —
   border-box keeps its height and its padding — and it is scoped to this row,
   so no other .v3-btn on the site is touched. */
.v3-dialog__actions .v3-btn { border: 1px solid transparent; }

/* The cancel button. Same shape as .v3-btn--outline but in the dialog's accent,
   so the danger set gets an error-red outline rather than the brand orange. */
.v3-dialog__cancel {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--v3-space-1);
	height: var(--v3-btn-h-lg);
	padding: 0 var(--v3-space-3);
	border: 1px solid var(--v3-border-orange);
	border-radius: var(--v3-radius-pill);
	background: transparent;
	box-shadow: 0 2px 3px 0 rgba(0, 0, 0, .25);
	color: var(--v3-dialog-accent);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-title);       /* 18px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	cursor: pointer;
}

.v3-dialog--danger .v3-dialog__cancel { border-color: var(--v3-error-500); }

/* DERIVED: Figma draws no hover for the cancel button. */
.v3-dialog__cancel:hover { background: rgba(0, 0, 0, .04); }

/* ---- the countdown ring ----------------------------------------------- */

/* 131.228 across with a 10.29 stroke — Ellipse 128/129/130 in 8031:10970,
   reproduced as one SVG so the arc can actually move. --v3-ring is the fraction
   still to go, 0..1, set by whoever is counting. */
.v3-dialog__ring {
	position: relative;
	display: block;
	width: 131.23px;
	height: 131.23px;
}

.v3-dialog__ring svg { display: block; width: 100%; height: 100%; }

.v3-dialog__ring-arc {
	transform: rotate(-90deg);
	transform-origin: 50% 50%;
	transition: stroke-dashoffset .3s linear;
}

.v3-dialog__ring-label {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	pointer-events: none;
}

.v3-dialog__ring-value {
	color: var(--v3-text-brand);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h3);          /* 32px SemiBold */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	font-variant-numeric: tabular-nums;
}

.v3-dialog__ring-unit {
	color: var(--v3-orange-700);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-title);       /* 18px Medium */
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
}

/* ---- the five help-way popups ----------------------------------------
   7928:9007 (دبلها), 8031:10970 (كلم المطنوخ / تحايل), 7928:8996 (اجابتين),
   7928:9063 (بلوك). Five ways, four frames — callfriend and cheat are the same
   countdown popup with a different number of seconds.

   Each is the alert above with one extra piece: the badge says what the way is,
   and the body carries whatever that way needs to explain itself — a points
   sum, a warning strip, a ring, or nothing at all.
   ---------------------------------------------------------------------- */

/* A round badge, sized rather than padded. The countdown popup's is a rounded
   rectangle around a tall icon (see .v3-dialog__badge); these three are circles
   around a glyph, and Figma draws them at three sizes. */
.v3-dialog__badge--circle {
	width: var(--v3-badge-size, 86px);
	height: var(--v3-badge-size, 86px);
	padding: 0;
	top: calc(var(--v3-badge-size, 86px) / -2 - 9px);
	border-radius: 50%;
	box-shadow: inset 0 7.7% 7.7% 0 rgba(255, 255, 255, .5);
}

/* "X2" — the badge IS the text, at 32 Bold. */
.v3-dialog__badge-text {
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h3);          /* 32 Bold */
	font-weight: var(--v3-fw-bold);
	line-height: 1;
}

.v3-dialog__badge--circle img {
	width: auto;
	height: 56%;
	object-fit: contain;
}

/* The tick badge is the biggest of the three and its glyph fills more of it. */
.v3-dialog__badge--tick { --v3-badge-size: 96.74px; }
.v3-dialog__badge--tick img { height: 73%; }

/* The second line of the exit confirm — its own line, same colour, heavier, and
   the 24px the text block puts between everything else — 8683:16269. */
.v3-dialog__ask {
	display: block;
	margin-top: var(--v3-space-5);
	font-weight: var(--v3-fw-semibold);
}

/* An illustration where a badge would go: 100 square, in the flow above the
   words rather than straddling the top edge — 8157:5996 in the pop frame. */
.v3-dialog__art {
	display: block;
	width: 100px;
	height: 100px;
	object-fit: contain;
}

/* An accented run inside the body — "ضعف النقاط" in 7928:9012. */
.v3-dialog__body b,
.v3-dialog__body strong {
	color: var(--v3-text-brand);
	font-weight: inherit;
}

/* ---- the points sum, 7928:9013 ---------------------------------------
   Reads 200 » 400, LEFT to right, which is what Figma draws: the chevrons
   point at the bigger number and the whole thing is a numeric expression, so it
   keeps LTR order inside an RTL dialog.
   ---------------------------------------------------------------------- */

.v3-dialog__swap {
	direction: ltr;
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
	padding: 11.58px 19.85px;
	border-radius: 9.92px;
	background: linear-gradient(to right, #fefcfa, var(--v3-warning-050));
}

.v3-dialog__swap-side {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6.62px;
	color: var(--v3-text-secondary);
	font-family: var(--v3-font);
	line-height: var(--v3-lh-auto);
}

.v3-dialog__swap-side--to { color: var(--v3-text-brand); }

.v3-dialog__swap-value {
	font-size: var(--v3-fs-h4);          /* 24 SemiBold */
	font-weight: var(--v3-fw-semibold);
}

.v3-dialog__swap-unit {
	font-size: var(--v3-fs-h5);          /* 20 Medium */
	font-weight: var(--v3-fw-medium);
}

.v3-dialog__swap-side--to .v3-dialog__swap-unit { font-weight: var(--v3-fw-regular); }

.v3-dialog__swap img { display: block; width: 39.69px; height: 39.69px; }

/* ---- the note strip, 7928:9071 ---------------------------------------- */

.v3-dialog__note {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 6.2px;
	width: 100%;
	min-height: 71px;
	padding: 6.2px 18.6px;
	border-radius: 8px;
	background: var(--v3-orange-100);
	color: var(--v3-orange-700);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);        /* 16 Medium */
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-normal);
	text-align: right;
}

.v3-dialog__note span { flex: 1 0 0; min-width: 0; }
.v3-dialog__note img { display: block; width: 31px; height: 31px; flex: 0 0 auto; }

/* The reminder under the points sum — 20 Medium, the darker orange. */
.v3-dialog__footnote {
	width: 100%;
	color: var(--v3-orange-700);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h5);          /* 20 Medium */
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-normal);
	text-align: center;
}

/* Figma gives each of these frames its own radius and padding. Close enough to
   one another that the alert's own are kept, except the two that are noticeably
   rounder. */
.v3-modal--alert.has-badge.is-double .v3-modal__dialog { border-radius: 29.77px; padding: 58px 28px 24px; }
.v3-modal--alert.has-badge.is-block .v3-modal__dialog  { border-radius: 32px;    padding: 58px 28px 33px; }


/* ---- the details shape — 8031:11035 -----------------------------------
   A title and a body and nothing else, so it is smaller in every direction and
   leans on type rather than on chrome: a BOLD 24 title over a 20 Medium body,
   where the confirm has SemiBold over 24 Regular.
   ---------------------------------------------------------------------- */

.v3-modal--alert.is-details .v3-modal__dialog {
	padding: 32px 50px;
	border-radius: 25.79px;
}

.v3-modal--alert.is-details .v3-dialog { gap: var(--v3-space-4); }
.v3-modal--alert.is-details .v3-dialog__text { gap: var(--v3-space-5); }

.v3-modal--alert.is-details .v3-dialog__title {
	font-size: var(--v3-fs-h4);          /* 24px Bold */
	font-weight: var(--v3-fw-bold);
	color: var(--v3-orange-600);         /* never the danger tone */
}

.v3-modal--alert.is-details .v3-dialog__body {
	font-size: var(--v3-fs-h5);          /* 20px Medium */
	font-weight: var(--v3-fw-medium);
}

.v3-modal--alert.is-details .v3-dialog__close {
	left: 23px;
	top: 23px;
	width: 40px;
	height: 40px;
}

/* ---- the report dialog ------------------------------------------------
   The one alert that is NOT built by dialog.js. It lives in the game fragment
   because /js/game.js opens it through MDB — #reportbtn carries data-mdb-toggle
   and report() clears that attribute after a successful send — so MDB keeps the
   mechanics and this only supplies the surface. Which means it must not use
   .v3-modal__dialog: that starts at opacity 0 and waits for a .v3-modal.is-open
   ancestor it would never get.
   ---------------------------------------------------------------------- */

.v3-report {
	position: relative;
	padding: 44px 28px;
	border: 0;
	border-radius: 18px;
	background: var(--v3-bg-page);
	box-shadow: 0 4px 10px 0 rgba(0, 0, 0, .25);
}

.v3-report .v3-dialog { gap: var(--v3-space-6); }

/* ---- narrow ----------------------------------------------------------- */

@media (max-width: 600px) {
	.v3-modal--alert .v3-modal__dialog { padding: 32px 16px; }
	.v3-report { padding: 32px 16px; }
	/* THE PADDING IS WHAT KEEPS THE TITLE OUT FROM UNDER THE BADGE, and at 24 it
	   did not: the badge hangs top:-40 and stands 74 tall, so 34 of it is INSIDE
	   the panel and the title started 10px up inside it. Every badged dialog on
	   a phone — the five help ways included — and nothing caught it, because the
	   two numbers live in different rules and the desktop pair is fine.

	   46 leaves 12 clear below the rect badge and below the 86 circle, and 6.6
	   below the 96.74 tick. Change either number and check the other. */
	.v3-modal--alert.has-badge .v3-modal__dialog { padding: 46px 16px 24px; margin-top: 40px; }
	.v3-dialog { gap: 28px; }

	/* NOT the circles: they size themselves from --v3-badge-size and derive their
	   own top from it, and this rule — later in the sheet, same specificity —
	   was overriding that with a flat -40 that only suits the rectangle. */
	.v3-dialog__badge:not(.v3-dialog__badge--circle) { top: -40px; padding: 14px 16px; }
	.v3-dialog__badge img { height: 46px; }
	/* THE CANCEL BUTTON COMES DOWN WITH .v3-btn. It is not one — it sets its own
	   56 so the danger set can take an error-red outline — so the phone rule up
	   in the button block passed it by and it stood 56 tall beside a 48 primary
	   in every phone dialog. It has to be HERE and not there: both selectors are
	   one class, a media query adds no specificity, and .v3-dialog__cancel's own
	   56 is written further down the file than that block — so a copy up there
	   loses on source order and changes nothing. Same token as .v3-btn either
	   way, so the two cannot drift apart again. */
	.v3-dialog__cancel { height: var(--v3-btn-h-md); font-size: var(--v3-fs-title); }

	.v3-dialog__title { font-size: var(--v3-fs-h4); }
	.v3-dialog__body { font-size: var(--v3-fs-body); }
	.v3-dialog__text { gap: 16px; }
	.v3-dialog__sparkle--b { display: none; }
	.v3-dialog__ring { width: 104px; height: 104px; }
	.v3-dialog__ring-value { font-size: var(--v3-fs-h4); }
	.v3-dialog__ring-unit { font-size: var(--v3-fs-caption); }
}

/* ==========================================================================
   SHORT, NOT NARROW — a phone lying on its side.

   Both boards are landscape-only, so the phone that plays them is about 930
   wide and about 430 tall. Every other breakpoint on this bar is a max-width,
   and 930 clears all of them: the bar kept its full desktop 111px and spent a
   QUARTER of the screen on itself, above a board that is the entire point of
   the page. Narrow-screen rules never fired because the screen is not narrow.

   So this one asks about the height instead, and it is deliberately last: on a
   device that is both short and narrow these are the tighter numbers and they
   should win, which source order gives them.

   Only the game bar is touched. The marketing pages are scrolled, so a tall
   header there costs nothing; a board that does not fit cannot be scrolled to.
   ========================================================================== */

@media (max-height: 520px) {
	/* 62 and not less, and the controls sit in the TOP 65% of it.

	   navbar-wave-mask.svg is 1446x111 and its bottom edge is a wave: the lowest
	   the fill is guaranteed to reach is y=84.96, or 76.5% of the height. Above
	   that line the bar is solid; below it, whether there is orange behind a
	   given pixel depends on where along the wave you are.

	   The desktop bar respects that without saying so — its 56px pills end at
	   y=79 of 111, which is 71%. The first version of this block did not: a 48px
	   inner in a 56px bar put the pills at 80%, past the trough, and they hung
	   out of the wave with cream behind them. So the bar keeps enough height for
	   its own shape rather than being squeezed to the smallest number that fits
	   the buttons. */
	.v3-navbar--game { height: 62px; padding-top: 8px; }
	.v3-navbar--game .v3-navbar__inner { height: 32px; padding: 0 12px; gap: var(--v3-space-2); }

	/* kept, not hidden — it is the only branding on the screen, and at this
	   size it still fits above the bar's own wave.

	   position AND transform are restored, and that is the whole point of this
	   rule rather than a tidy-up. The max-width: 900px block above makes this
	   logo `position: static` so the marketing bar can stack it into the flow,
	   and a phone in landscape matches BOTH blocks. Setting `display: block`
	   here without putting it back in its own layer left a 34px image sitting in
	   the bar's normal flow, pushing .v3-navbar__inner from y=8 down to y=42 —
	   past the 47px line where this bar's wave stops being solid. The controls
	   then hung over the cream with their labels unreadable, which is what the
	   in-game "corrupted on landscape" report was showing above the board. */
	.v3-navbar--game .v3-navbar__logo--center {
		display: block;
		position: absolute;
		left: 50%;
		transform: translateX(-50%);
		top: 4px;
		width: 96px;
		height: 34px;
	}

	.v3-navbar--game .v3-navbar__game-status { gap: var(--v3-space-2); min-width: 0; }
	.v3-navbar--game .v3-navbar__game-actions { height: 32px; gap: var(--v3-space-2); }

	.v3-navbar--game .v3-navbar__turn,
	.v3-navbar--game .v3-navbar__pill,
	.v3-navbar--game .v3-btn {
		height: 32px;
		padding: 0 10px;
		font-size: 13px;
	}
	.v3-navbar--game .v3-navbar__turn img,
	.v3-navbar--game .v3-navbar__pill img { width: 15px; height: 15px; }

	/* .v3-btn draws Figma's two shine arcs at a fixed 30x24 and 13x10, which is
	   right on a 56px pill and covers the label on a 34px one. */
	.v3-navbar--game .v3-btn::after { top: 3px; right: 4px; width: 20px; height: 16px; }
	.v3-navbar--game .v3-btn::before { top: 5px; left: 8px; width: 9px; height: 7px; }

	.v3-navbar--game .v3-navbar__team {
		font-size: 14px;
		padding: 4px 6px;
	}
}

/* ==========================================================================
   The finish — Figma 8658:7937 (trivia) and 8658:8381 (وصلها).

   The only screen in either game that changes the page's ground: everything
   else sits on the cream, this sits on the brand orange with a band over it.
   The band, the rays and the confetti are all FIXED layers rather than children
   in flow, because the band starts behind the navbar — its top edge is the top
   of the frame, not the top of this element.

   THE TWO FRAMES ARE ONE COMPONENT. They differ in the band's colour — dark
   green for trivia, the page cream for وصلها — and in what the text on it has
   to be to stay readable. Those are the four --ge-* tokens below; .v3-ge--light
   is the وصلها half. Everything else, including the cup and the confetti, is
   shared, which is why this lives here rather than in either page's sheet.

   The team cards read --lt-fill / --lt-border when they are set and fall back to
   the win/lose tokens when they are not. وصلها sets them per card because both
   teams pick their own colour at creation; trivia has no such thing and takes
   the fallback without asking for it.
   ========================================================================== */

.v3-ge {
	/* trivia's half of the pair; .v3-ge--light overrides all four */
	--ge-band: var(--v3-green-900);
	--ge-fg: var(--v3-text-inverse);
	--ge-ray: rgba(255, 255, 255, .042);
	/* FILLED, not outlined. .v3-navbar__pill is transparent with a white hairline,
	   which works in the game bar and reads as a ghost on a finish screen — on
	   وصلها’s cream band a light outline on a light ground was barely a button at
	   all. Both finishes now fill it with the brand orange, so it is a solid pill
	   beside لعبة جديدة’s white one and legible on either ground. */
	--ge-again-bg: var(--v3-orange-500);
	--ge-again-fg: var(--v3-text-inverse);
	--ge-again-border: var(--v3-orange-500);

	position: relative;
	display: grid;
	align-content: center;
	min-height: 0;
	/* 92/204 rather than an even split: Figma puts the block at y=203.5 in a
	   790px frame, which is 55px above centre. As on the board, the two paddings
	   carry the bias and the block still centres in what is left. */
	padding-block: clamp(16px, 11.5vh, 160px) clamp(24px, 25.5vh, 320px);
	padding-inline: 6.94vw;              /* 100/1440 */

	container-type: inline-size;
	container-name: ge;
}

/* The dark band. A mask over a flat fill, the same technique as the navbar's
   wave (§ components.css) and for the same reason: the exported SVG carries its
   own filter, which rasterises at the file's size and goes soft when scaled.

   Fixed and full-viewport: the shape is 1440x794 measured from the top of the
   FRAME, so it has to reach up behind the 111px bar. The navbar's own z-index
   (21) keeps it painting on top. */
.v3-ge::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 0;
	background: var(--ge-band);
	-webkit-mask: url("/img/v3/game/ended-band.svg") no-repeat center / 100% 100%;
	mask: url("/img/v3/game/ended-band.svg") no-repeat center / 100% 100%;
	pointer-events: none;
}

/* Light rays fanning from a point below the bottom edge, over BOTH grounds.
   Measured off the reference: white at 4.2% — #04372A reads 15,63,51 under a
   ray and 4,55,42 beside one, and the same alpha explains the orange.

   DERIVED: Figma draws six rectangles of uneven width; an even fan is the same
   thing to look at and does not need six more nodes. */
.v3-ge__rays {
	position: fixed;
	inset: 0;
	z-index: 0;
	background: repeating-conic-gradient(
		from 200deg at 50% 108%,
		var(--ge-ray) 0deg 7deg,
		transparent 7deg 20deg
	);
	/* Faded out over the lower third. Figma's Lightness frame sits mostly BELOW
	   the artboard, so only the upper part of the fan is in shot and the orange
	   along the bottom is clean; an unfaded conic gradient stripes it. */
	-webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 82%);
	mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 82%);
	pointer-events: none;
}

/* DERIVED PLACEMENT. The field itself is Figma's, keyed off its own export
   (8658:7940); where the two copies sit is not — the group's coordinates are
   reported in a rotated space, and matching the export against the reference
   did not converge. Two mirrored copies read the way the frame does. */
.v3-ge__confetti {
	position: fixed;
	z-index: 0;
	width: 887px;
	height: auto;
	opacity: .9;
	/* The export has a hairline stroke baked along its BOTTOM edge, and the
	   second copy puts that edge across the middle of the screen — a thin line
	   ruled from the standings to the right margin, on both boards. Cropping the
	   last 2% removes it and costs nothing: the field is sparse dots, so a cut
	   there leaves no visible edge of its own, which is exactly why the line
	   showed and the boundary around it did not. */
	clip-path: inset(0 0 2% 0);
	pointer-events: none;
	-webkit-user-select: none;   /* Safari, iOS Safari */
	user-select: none;
}

.v3-ge__confetti--a { left: -40px;  bottom: 0; }
.v3-ge__confetti--b { right: -60px; top: 40px; transform: scaleX(-1); }

/* 375 x 562.5 at the frame's right edge, its foot on the bottom. Anchored to
   the bottom rather than to y=228, so a taller window does not float it. */
.v3-ge__cup {
	position: fixed;
	right: 0;
	bottom: 0;
	z-index: 1;
	display: block;
	width: clamp(140px, 26.04vw, 640px); /* 375/1440 */
	height: auto;
	aspect-ratio: 375 / 562.5;
	object-fit: contain;
	pointer-events: none;
	-webkit-user-select: none;   /* Safari, iOS Safari */
	user-select: none;
}

/* 672 of the 1240 column at the design width, and a share of it above that —
   see the note on the board for why any of this is a share at all. Its own
   container, so the standings and the buttons can be shares of IT. */
.v3-ge__inner {
	container-type: inline-size;
	container-name: geinner;

	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 3.87cqw;                        /* 48/1240 */
	width: 100%;
	max-width: 54.19cqw;                 /* 672/1240 */
	margin: 0 auto;
}

.v3-ge__title {
	margin: 0;
	color: var(--ge-fg);
	font-family: var(--v3-font);
	font-size: 9.52cqw;                  /* 64 of the 672 column */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	text-align: center;
}

/* ---- the standings ---------------------------------------------------- */

.v3-ge__ranks {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 4.31cqw;                        /* 29 */
	width: 100%;
	flex-wrap: wrap;
}

/* 320 x 156 with the score pill hanging over its bottom half — the same
   two-piece card the dock and the question rail use, in the win/lose palette. */
.v3-ge__team {
	container-type: inline-size;
	container-name: geteam;

	position: relative;
	flex: 0 1 47.62cqw;                  /* 320 of the 672 column */
	min-width: 0;
	aspect-ratio: 320 / 156;
	border-radius: 5.36cqw;              /* 36 — a share of the COLUMN, since a
	                                        container cannot measure itself */
	background: var(--lt-fill, var(--v3-lose-500));
	padding: .6cqw 1.79cqw 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: .91cqw;
	/* NOT overflow: hidden. The score pill below is pinned to this card's bottom
	   edge and is rounded LESS than the card is, so clipping shaved its two
	   bottom corners and cut its ring open — Figma draws that pill whole. Nothing
	   else here needs the clip: the verdict and the name truncate themselves. */
	text-align: center;
}

.v3-ge__team--won { background: var(--lt-fill, var(--v3-win-500)); }

.v3-ge__verdict {
	color: var(--v3-green-050);
	font-family: var(--v3-font);
	font-size: 10cqw;                    /* 32 of the 320 card */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	padding-top: 2.88cqw;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 100%;
}

.v3-ge__name {
	color: var(--v3-green-050);
	font-family: var(--v3-font);
	font-size: 7.5cqw;                   /* 24 of the 320 card */
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	max-width: 100%;
}

/* Pinned to the card's bottom rather than laid out after the names, so a long
   team name cannot push it out of the card. */
.v3-ge__score {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	height: 19.06cqw;                    /* 61 */
	border: 1.2cqw solid var(--lt-border, var(--v3-lose-700));
	border-radius: 7.5cqw;
	background: var(--v3-green-050);
	color: var(--lt-border, var(--v3-lose-700));
	font-family: var(--v3-font);
	font-size: 7.5cqw;                   /* 24 Bold */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
}

.v3-ge__team--won .v3-ge__score {
	border-color: var(--lt-border, var(--v3-win-700));
	color: var(--lt-border, var(--v3-win-700));
}

/* وصلها's half — 8658:8381. The band becomes the page cream, so everything
   written on it flips from light to dark, and the rays have to lighten the
   cream instead of the dark green. */
.v3-ge--light {
	--ge-band: var(--v3-bg-page);
	--ge-fg: var(--v3-green-900);
	--ge-ray: rgba(255, 255, 255, .55);
	/* Same filled pill as the trivia finish — see the note there. */
	--ge-again-bg: var(--v3-orange-500);
	--ge-again-fg: var(--v3-text-inverse);
	--ge-again-border: var(--v3-orange-500);
}

/* ---- the two ways out ------------------------------------------------- */

.v3-ge__cta {
	display: flex;
	align-items: center;
	gap: 2.98cqw;                        /* 20 */
}

.v3-ge__cta > * {
	width: 26.79cqw;                     /* 180 */
	height: 8.33cqw;                     /* 56  */
	font-size: 2.68cqw;                  /* 18  */
}

/* The in-bar outlined pill, reused: same border, shadow and type. Only its
   colour differs — on the dark band the label is white, not the bar's warm
   off-white. Restated in every link state because this one is an <a>. */
.v3-ge__again,
.v3-ge__again:link, .v3-ge__again:visited, .v3-ge__again:hover,
.v3-ge__again:focus, .v3-ge__again:active {
	border-color: var(--ge-again-border);
	background: var(--ge-again-bg);
	color: var(--ge-again-fg);
	text-decoration: none;
}

/* ==========================================================================
   The finish, narrower than the design.
   ========================================================================== */

@media (max-width: 1200px) {
	.v3-ge { padding-inline: 40px; padding-block: 6vh 14vh; }
	.v3-ge__inner { max-width: min(100%, 62cqw); }
	.v3-ge__confetti { width: 620px; }
}

@media (max-width: 900px) {
	.v3-ge { padding-inline: 20px; padding-block: 3vh 4vh; }
	.v3-ge__inner { max-width: min(100%, 78cqw); }
	/* Below the design width a share of the viewport stops being readable, so
	   the type takes a floor and the cup gets out of the way. */
	.v3-ge__title { font-size: max(20px, 9.52cqw); }
	.v3-ge__verdict { font-size: max(13px, 10cqw); }
	.v3-ge__name { font-size: max(11px, 7.5cqw); }
	.v3-ge__score { font-size: max(12px, 7.5cqw); }
	.v3-ge__cta > * { min-width: 120px; height: max(38px, 8.33cqw); font-size: max(12px, 2.68cqw); }
	.v3-ge__cup { width: clamp(110px, 20vw, 200px); }
	.v3-ge__confetti { width: 420px; }
}

/* ==========================================================================
   THE APP CHROME — Figma 8683:14802 (header) and 8681:14758 (bottom bar).

   Portrait, 375 wide. Every isApp screen carries both, which is why they live
   here rather than in a page sheet.

   THE DEVICE'S STATUS BAR IS NOT DRAWN. Figma's header measures 119 because it
   includes the phone's clock, cellular, wifi and battery. What is built is the
   72px content row and the wave behind it, and header-wave.svg is cropped to
   match.

   BUT THE ROW HAS TO START BELOW THE STATUS BAR, and that is not free.
   layouts/head.ejs asks for viewport-fit=cover, which tells iOS to lay the page
   out edge to edge — under the Dynamic Island at the top and under the home
   indicator at the bottom. This block used to assume the webview sat below all
   of that and reserved nothing, so on a notched iPhone the top ~54px of the bar
   — its content row AND the solid part of its wave — was behind the clock.

   env(safe-area-inset-*) is 0 wherever there is no inset, so the calc()s below
   change nothing on Android, on desktop, or in a webview that already insets.
   They only give back the room the system is actually covering.
   ========================================================================== */

/* Every app screen's content sits between the two. The room to scroll past
   the bar is NOT here any more — .v3-apptabs__gap is, and it comes with the
   bar rather than with the page. See the note in layouts/app-tabbar.ejs. */
.v3-apppage {
	background: var(--v3-bg-page);
	min-height: calc(100dvh - 72px - env(safe-area-inset-top, 0px));
}

.v3-appbar {
	position: relative;
	z-index: 21;                         /* navigation, so the navbar's band */
	/* 72 of bar, plus whatever the phone is covering at the top */
	height: calc(72px + env(safe-area-inset-top, 0px));
	padding-top: env(safe-area-inset-top, 0px);
	flex: 0 0 auto;

	/* WHAT SITS BEHIND THE WAVE, and it must not be the page.

	   The wave is a curve, so wherever it rides above the bar's full height
	   there is bar left over with nothing painted on it — and the page's cream
	   showed through as a band between the orange and the section below. Figma
	   has no such band: the dark green runs UP behind the bar and the wave is
	   laid over it.

	   The colour belongs to the page rather than to the bar, because the next
	   screen may not be green. Home sets it; anything that does not gets the
	   page ground, which is at least not a seam. */
	background: var(--v3-appbar-behind, var(--v3-bg-page));
}

/* The wave, as a MASK over a flat fill rather than the exported SVG itself:
   that export carries its own drop-shadow filter, which rasterises at the
   file's size and goes soft the moment it is scaled. Same technique as the
   marketing navbar's.

   79 tall against the bar's 72, so the trough hangs 7px into whatever follows
   — which is the point. The boundary between the orange and the section under
   it IS this curve. */
.v3-appbar::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: calc(79px + env(safe-area-inset-top, 0px));
	background: var(--v3-bg-brand);
	pointer-events: none;

	/* HOW FAR DOWN THE BAR IS A PLAIN RECTANGLE. Everything above this is full
	   width with square corners; only the strip below it curves. Raise it for a
	   shallower wave, lower it for a deeper one — the curve keeps its shape
	   either way, because it is the same artwork squashed into what is left. */
	/* The inset is added to the FLAT part, not shared across the whole shape:
	   the curve then keeps both its height and its distance below the content
	   row, and only the square top grows. */
	--wave-flat: calc(46px + env(safe-area-inset-top, 0px));

	/* AND HOW MUCH WIDER THAN THE SCREEN THE CURVE IS DRAWN.

	   This is not decoration, it is the reason the corners looked bitten off.
	   Figma's vector is 395 across on a 375 screen — it hangs 14 off the left
	   and 6 off the right, so the steep rises at its two ends sit OFF-SCREEN and
	   what you see is the gentle middle. Stretched to exactly 100% those ends
	   come into view, and the shape pinches to nothing before it reaches either
	   edge: at x=0 there was no orange in the column at all.

	   395/375 = 105.33%. The position keeps the overhang split the way Figma
	   splits it — 14 of the 20 surplus pixels on the left, which is 66% of it. */
	--wave-over: 105.33%;

	-webkit-mask-image: linear-gradient(#000, #000), url("/img/v3/app/header-wave.svg");
	mask-image: linear-gradient(#000, #000), url("/img/v3/app/header-wave.svg");
	-webkit-mask-size: 100% var(--wave-flat), var(--wave-over) calc(79px - var(--wave-flat));
	mask-size: 100% var(--wave-flat), var(--wave-over) calc(79px - var(--wave-flat));
	-webkit-mask-position: left top, 66% bottom;
	mask-position: left top, 66% bottom;
	-webkit-mask-repeat: no-repeat, no-repeat;
	mask-repeat: no-repeat, no-repeat;
}

.v3-appbar__inner {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: 72px;
	padding: 0 20px;
}

/* ---- the balance ------------------------------------------------------- */

/* direction: ltr because this is a glyph and a number, and Figma draws the cup
   to the LEFT of the count. In an RTL row the first child renders rightmost,
   so without this the cup would swap sides with its own figure. */
.v3-appbar__coins {
	direction: ltr;
	display: flex;
	align-items: center;
	gap: 8px;
	text-decoration: none;
}
.v3-appbar__coins:link, .v3-appbar__coins:visited,
.v3-appbar__coins:hover, .v3-appbar__coins:focus, .v3-appbar__coins:active {
	color: var(--v3-text-inverse);
	text-decoration: none;
}

.v3-appbar__cup {
	display: block;
	width: 24px;
	height: 24px;
	background: var(--v3-white);
	/* The design-system cup, not the header's own export: that export is a
	   SINGLE path out of a seven-path glyph, so it masked to the trophy's bowl
	   with no handles and no base. /img/v3/cup.svg is the whole thing and is
	   already in the tree for the trivia points badge. */
	-webkit-mask: url("/img/v3/cup.svg") no-repeat center / contain;
	mask: url("/img/v3/cup.svg") no-repeat center / contain;
}

/* وصلها's balance is not the same currency, so it does not wear the same mark.
   The hexagon is the game's own symbol everywhere else — the board, the plan
   cards' tiles, app/plans.ejs's artwork — and both files are a single filled
   path, so they mask to a solid white glyph the same way. */
.v3-appbar__cup--letter {
	-webkit-mask-image: url("/img/v3/pricing/hex.svg");
	mask-image: url("/img/v3/pricing/hex.svg");
}

/* Figma's Line 61 — a hairline between the cup and the figure, taller than
   either of them. A border rather than an element: it has no other job. */
.v3-appbar__count {
	padding-inline-start: 8px;
	border-inline-start: 1px solid rgba(255, 255, 255, .45);
	line-height: 40px;
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h4);
	font-weight: var(--v3-fw-bold);
	font-variant-numeric: tabular-nums;
}

/* ---- the logo, and the switcher that usually stands there --------------- */

/* On الحساب there is no per-game data, so the logo stands where the
   اللعبة الجماعية | وصلها control sits on the other four screens. */
.v3-appbar__logo {
	display: block;
	width: auto;
	height: 34px;
	object-fit: contain;
}

/* ---- اللعبة الجماعية | وصلها, Figma 8683:14971 -------------------------- */

.v3-appswitch {
	display: flex;
	align-items: stretch;
	width: 155px;
	height: 35px;
	border-radius: 40px;
	background: var(--v3-green-050);
	box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .25);
	/* the lit half is a 24-radius pill inside a 40-radius one; this is what
	   trims its corners back to the outer shape */
	overflow: hidden;
}

/* NOT flex: 1 0 0 — the two labels are wildly different lengths (اللعبة
   الجماعية against وصلها) and equal halves would clip the long one. A basis of
   `auto` starts each half at its own text width and shares only the slack, so
   the long label gets the room it needs and the split stays sensible if either
   label is ever reworded. */
.v3-appswitch__half {
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 0;
	padding: 6px 8px 8px;
	border-radius: 24px;
	font-family: var(--v3-font);
	font-size: 12px;
	font-weight: var(--v3-fw-semibold);
	line-height: 1;
	text-align: center;
	white-space: nowrap;
}

/* the colour in every link state — MDB's a:hover would otherwise win */
.v3-appswitch__half:link, .v3-appswitch__half:visited,
.v3-appswitch__half:hover, .v3-appswitch__half:focus, .v3-appswitch__half:active {
	color: var(--v3-orange-600);
	text-decoration: none;
}

/* Icons/Green/Primary, which is a third green — not green-800. */
.v3-appswitch__half.is-active,
.v3-appswitch__half.is-active:link, .v3-appswitch__half.is-active:visited,
.v3-appswitch__half.is-active:hover, .v3-appswitch__half.is-active:focus,
.v3-appswitch__half.is-active:active {
	position: relative;
	background: var(--v3-green-icon);
	color: var(--v3-green-050);
}

/* The lit half carries the same gloss arc every solid control in v3 has —
   switch-shine.svg, the web switcher's own asset, stretched to the 11x6 the
   design draws here. It sits on the half's OUTER corner, which is the right
   one when اللعبة الجماعية is lit and the left one when وصلها is, hence two
   rules rather than a single `right`. */
.v3-appswitch__half.is-active::after {
	content: "";
	position: absolute;
	top: 4.5px;
	width: 11px;
	height: 6px;
	background: url("/img/v3/switch-shine.svg") no-repeat center / 100% 100%;
	pointer-events: none;
}
.v3-appswitch__half.is-active:first-child::after { right: 6.33px; }
.v3-appswitch__half.is-active:last-child::after  { left: 6.33px; transform: scaleX(-1); }

/* ---- the avatar -------------------------------------------------------- */

/* MDB's a:hover paints links blue at (0,1,1), which outranks a bare class —
   so every v3 anchor states its own colour in every link state. Nothing here
   is text, but the rule is about the anchor, not its contents. */
.v3-appbar__avatar:link, .v3-appbar__avatar:visited,
.v3-appbar__avatar:hover, .v3-appbar__avatar:focus, .v3-appbar__avatar:active {
	color: var(--v3-text-inverse);
	text-decoration: none;
}

.v3-appbar__avatar {
	position: relative;
	display: block;
	width: 48px;
	height: 48px;
	flex: 0 0 auto;
}

/* The tint is there for PHOTOS — it fills the corners while one loads and
   backs anything with transparency in it. */
.v3-appbar__avatar img {
	display: block;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	object-fit: cover;
	background: var(--v3-green-100);
}

/* NOT for the default. The tint is there to sit behind a user's photo while
   it loads; the default avatar is an opaque square that would hide it anyway,
   and when this was a transparent glyph the tint showed AROUND the figure as
   a second disc inside the ring. */
.v3-appbar__avatar--default img { background: none; }

.v3-appbar__dot {
	position: absolute;
	right: 1px;
	bottom: 3px;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--v3-success-500);
	box-shadow: 0 0 0 2px var(--v3-bg-brand);
}

/* ==========================================================================
   The bottom bar.
   ========================================================================== */

/* 75 of bar plus 20 of air, in normal flow, so the last thing on any app
   screen has somewhere to scroll to. Rendered by layouts/app-tabbar beside
   the bar itself; nothing else needs to know about it. */
.v3-apptabs__gap {
	flex: 0 0 auto;
	/* grows with the bar it is standing in for — see the inset note above */
	height: calc(95px + env(safe-area-inset-bottom, 0px));
}

.v3-apptabs {
	position: fixed;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 21;
	display: flex;
	align-items: stretch;
	/* 75 of bar, plus the strip the home indicator sits on. Padding rather than
	   height alone, so the icons and labels move up out from under it instead of
	   the bar simply getting taller around them. */
	height: calc(75px + env(safe-area-inset-bottom, 0px));
	padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* THE NOTCH, and it is on a PSEUDO-ELEMENT for a reason.

   In Figma the bar is a boolean subtract — a rounded rectangle minus a 66px
   circle — so it is a shape, not a rectangle with a button parked on it. Mask
   it on .v3-apptabs itself, though, and the mask clips the element's CHILDREN
   too: the float button sits precisely in the notch, which is the one place the
   mask makes transparent, so the button vanished entirely. The background gets
   the mask; the contents stay unmasked.

   Two mask layers rather than one stretched shape: the exported silhouette is
   375 wide, and stretching it to a 430px phone would turn the circular bite
   into an ellipse while the button inside it stayed round. So the silhouette is
   pinned to the RIGHT at its natural size and a plain gradient fills everything
   to its left. The gradient overruns the silhouette's own left corner by 30px
   on purpose — mask layers add — and the radius here puts the real corner
   back. */
.v3-apptabs::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 26px 26px 0 0;
	background: var(--v3-green-800);

	/* THE NOTCH IS DRAWN, NOT EXPORTED, because it MOVES. Figma's silhouette is
	   a 375-wide boolean — a rounded rectangle minus a 66px circle — and pinning
	   it to the right meant the bite was always under الرئيسية. It belongs under
	   whichever tab is current: the design's plans frame puts it at 50%+77.5,
	   over الباقات, with the float button and its icon moved to match.

	   A radial-gradient mask is that same shape and takes the position as a
	   variable. The rounded corners come from border-radius, so the mask has
	   only one job: punch a circle of r=33 whose centre sits 1px above the bar's
	   top edge, which is exactly where Figma's ellipse is. Half a pixel of
	   feather keeps the rim from aliasing. */
	-webkit-mask-image: radial-gradient(circle 33px at var(--notch-x, 90%) -1px, transparent 0 33px, #000 33.5px);
	mask-image: radial-gradient(circle 33px at var(--notch-x, 90%) -1px, transparent 0 33px, #000 33.5px);
	pointer-events: none;
}

/* THE FIVE LABELS SHARE ONE LINE, so the slot is placed rather than centred.

   Every slot in Figma is the same two boxes: a 36x36 icon group at y=7.5 and a
   label at y=48.5, 14 tall — الرئيسية included, whose icon group is EMPTY
   because the button floats over it. Centring the column instead of pinning it
   breaks that in two ways at once: home has only a label in flow, so it floated
   to the middle of the bar, and الألعاب's taller icon pushed its label down a
   couple of pixels. Both are the same mistake — letting content decide a
   position the design fixes.

   7.5 + 36 + 5 = 48.5, which is where the label goes. */
.v3-apptabs__item {
	position: relative;                  /* above the masked background */
	z-index: 1;
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-start;
	gap: 5px;
	min-width: 0;
	padding-top: 7.5px;
	text-decoration: none;
}
/* the colour, not only the underline — see the note on the avatar above. The
   label sets its own on top of this; what matters is that MDB's blue never
   reaches the anchor. */
.v3-apptabs__item:link, .v3-apptabs__item:visited,
.v3-apptabs__item:hover, .v3-apptabs__item:focus, .v3-apptabs__item:active {
	color: var(--v3-green-050);
	text-decoration: none;
}

/* The box is the design's 36x36 icon GROUP, and `contain` is right because
   each SVG *is* that whole group — exported with its invisible Ellipse 13 — with
   the real 24x24 glyph sitting in the middle of it. Sizing the mask to 24
   instead scales the group down, and the glyph inside it lands at 16: two
   thirds, which is exactly how much smaller these read than the design. */
/* THE GLYPH IS A VARIABLE ON THE ITEM, not a rule on its icon, because the
   float button needs the same one: whichever tab is current draws its icon
   inside the button instead of in its slot. One declaration, two consumers. */
.v3-apptabs__item--account { --tab-icon: url("/img/v3/app/tab-account.svg"); }
.v3-apptabs__item--plans   { --tab-icon: url("/img/v3/app/tab-plans.svg"); }
/* Two houses, and they are different drawings: the slot's is an outline in
   a 36 group, the button's is the solid one Figma puts inside float-btn. */
.v3-apptabs__item--home    { --tab-icon: url("/img/v3/app/tab-home-slot.svg"); }
/* this one's group is 32 rather than 36 (Figma's Group 29), so `contain` on a
   36 box would stretch its glyph past 24 — pin it to the size it was drawn at */
.v3-apptabs__item--history {
	--tab-icon: url("/img/v3/app/tab-history.svg");
	--tab-icon-size: 32px 32px;
}

.v3-apptabs__icon {
	display: block;
	flex: 0 0 auto;
	width: 36px;
	height: 36px;
	background: var(--v3-green-050);
	-webkit-mask: var(--tab-icon) no-repeat center / var(--tab-icon-size, contain);
	mask: var(--tab-icon) no-repeat center / var(--tab-icon-size, contain);
}

/* الألعاب is the logo mark, and it is artwork rather than a glyph — a mask
   would flatten it to one colour. */
.v3-apptabs__item--games .v3-apptabs__icon {
	background: url("/img/v3/app/tab-games.png") no-repeat center / 30.65px 29.74px;
	-webkit-mask: none;
	mask: none;
}

/* 12 in a 14-tall line box, NOT 14/1 — which is the same 14px box but glyphs
   an eighth too big. Figma only gives the box (14), so the size came from
   measuring the rendered ink against the design's: every one of the five came
   out 1.175x too wide, and 14 / 1.175 is 12. The explicit line-height is what
   keeps the box at 14 and the label on its 48.5 line. */
.v3-apptabs__label {
	color: var(--v3-green-050);
	font-family: var(--v3-font);
	font-size: 12px;
	font-weight: var(--v3-fw-bold);
	line-height: 14px;
	white-space: nowrap;
}

.v3-apptabs__item.is-active .v3-apptabs__label { color: var(--v3-orange-500); }

/* ---- the raised button, which is the ACTIVE tab ------------------------ */

/* IT IS NOT HOME'S. It was built as home's because Home was the first screen
   drawn, and on that frame the button sits over الرئيسية with the house in it.
   The pricing frame settles what it really is: there the button is over
   الباقات, carries the ticket, and الرئيسية has gone back to being an ordinary
   tab with a house icon. The button is how the bar says "you are here".

   So the active item's icon stops being a 36 glyph in the slot and becomes the
   56 button over the notch, drawing that item's own --tab-icon inside itself.
   The notch follows through the same --notch-x the mask above reads; the view
   sets it, because it knows which tab is current. */
.v3-apptabs__item.is-active {
	position: static;                    /* so the button positions on the bar */
	padding-top: 48.5px;                 /* nothing is in flow but the label */
}

.v3-apptabs__item.is-active .v3-apptabs__icon {
	position: absolute;
	left: var(--notch-x, 90%);
	/* 32 clear of the bar's top edge, which is where Figma puts it: the button
	   is at y=-2 against a bar starting at y=30. At 24 it sat down in the notch
	   instead of standing out of it.

	   PLUS THE HOME INDICATOR, and leaving that out is what broke this on every
	   phone that has one. bottom is measured from the containing block's padding
	   box, and the bar's padding box runs to the bottom of the SCREEN — it is
	   75 tall plus the safe-area strip. So a flat 51 put the button 51 above the
	   screen's edge instead of 51 above the bar's, which on a 34px indicator
	   dropped it 34px down into the bar, on top of its own label. The notch does
	   not move with it — the mask measures from the TOP — so the bite and the
	   button came apart as well.

	   A phone without one has a 0 inset and lands where it always did. */
	bottom: calc(51px + env(safe-area-inset-bottom, 0px));   /* 75 - 56 + 32 */
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background: var(--v3-orange-500);
	box-shadow: 0 0 10px 0 rgba(242, 122, 61, .85);
	-webkit-mask: none;
	mask: none;
	transform: translateX(-50%);
}

/* The glyph sits inside the button rather than being the button. The inset is
   the GROUP's size, not the glyph's: these SVGs are the design's 36x36 icon
   group with a 24 glyph in the middle, so a 24 box would scale the group and
   land the glyph at 16 — the same two-thirds mistake the slots had. */
.v3-apptabs__item.is-active .v3-apptabs__icon::after {
	content: "";
	position: absolute;
	inset: 10px;                         /* a 36 group inside the 56 disc */
	background: var(--v3-white);
	-webkit-mask: var(--tab-icon) no-repeat center / contain;
	mask: var(--tab-icon) no-repeat center / contain;
}

/* ألعابي السابقة's group is 32 */
.v3-apptabs__item--history.is-active .v3-apptabs__icon::after { inset: 12px; }

/* and home swaps drawings: the button carries the solid house, at the 30 it is
   drawn at inside Figma's float-btn rather than the slot outline's 36 */
.v3-apptabs__item--home.is-active .v3-apptabs__icon::after {
	inset: 13px;
	-webkit-mask-image: url("/img/v3/app/tab-home.svg");
	mask-image: url("/img/v3/app/tab-home.svg");
}

/* and الألعاب's mark is artwork on the button too, so it keeps its picture */
.v3-apptabs__item--games.is-active .v3-apptabs__icon {
	background: var(--v3-orange-500);
}
.v3-apptabs__item--games.is-active .v3-apptabs__icon::after {
	inset: 13px;
	background: url("/img/v3/app/tab-games.png") no-repeat center / 30.65px 29.74px;
	-webkit-mask: none;
	mask: none;
}


/* A bar with no current tab keeps its rounded top and loses the bite. The
   notch exists to make room for the raised button, and a screen that is not a
   tab has no button to make room for — تسجيل الدخول showed the hole without
   it. See the note in views/v3/layouts/app-tabbar.ejs. */
.v3-apptabs--flat::before {
	-webkit-mask-image: none;
	mask-image: none;
}

/* ==========================================================================
   ARRIVAL — what the payment flow leaves on the URL.

   Two small pieces, both built by /js/v3/arrival.js: a line above the balance
   cards when a sale has just gone through, and the gateway's own code inside
   the failure dialog. Everything else it shows is the ordinary popup.
   ========================================================================== */

/* Above the two cards in رصيدك, when ?purchase_success= brought you here. It
   is the sale being confirmed, so it reads as success rather than as a notice
   — and the dialog under it is already answering "what is my balance now". */
.v3-arrival-note {
	margin: 0 0 var(--v3-space-5);
	padding: var(--v3-space-3) var(--v3-space-4);
	border: 1px solid var(--v3-success-500);
	border-radius: var(--v3-radius-md);
	background: var(--v3-white);
	color: var(--v3-success-700);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-normal);
	text-align: center;
}

/* The gateway's result code and its English description, inside the failure
   dialog. LTR because it is neither Arabic nor ours: OPPWA's table supplies
   both, and reversing them would make a support call harder, not easier. */
.v3-arrival-code {
	display: block;
	margin-top: var(--v3-space-4);
	padding: var(--v3-space-2) var(--v3-space-3);
	border-radius: var(--v3-radius-sm);
	background: var(--v3-disabled-bg);
	color: var(--v3-neutral-600);
	font-size: var(--v3-fs-caption);
	font-weight: var(--v3-fw-regular);
	line-height: var(--v3-lh-normal);
	text-align: center;
}

@media (max-width: 600px) {
	.v3-arrival-note { font-size: var(--v3-fs-caption); }
}

/* ==========================================================================
   المصادقة الثنائية — the password and code prompts.

   These began on the login page, where the second step of signing in asks for
   a 2FA code (/js/v3/auth.js). The account page's المصادقة الثنائية flow then
   wanted the same field in the same dialog four more times
   (/js/v3/my-account-2fa.js), so they moved here from pages/auth.css — two
   pages is where a page sheet stops being the right home.
   ========================================================================== */

/* The dialog body is 24px because it is usually the whole message; here it is
   one line of instruction above the thing you actually came to do. */
.v3-2fa .v3-dialog__body {
	font-size: var(--v3-fs-body);
	color: var(--v3-text-tertiary);
}

.v3-2fa__field {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-2);
	margin-top: var(--v3-space-5);
	text-align: right;
}

/* CENTRED AND SPACED, unlike every other .v3-input, which is right-aligned
   Arabic. This one holds six digits and nothing else: latin, LTR whatever the
   page direction, and tracked out so the count is readable at a glance.

   The PASSWORD field beside it deliberately does not carry this class — a
   password is not six digits and centring it would be a lie about its shape. */
.v3-2fa__input {
	direction: ltr;
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h4);
	font-weight: var(--v3-fw-semibold);
	letter-spacing: 0.32em;
	text-align: center;
	/* the tracking is applied to the right of each glyph, including the last,
	   so the run sits off-centre by half a space without this */
	text-indent: 0.32em;
}

.v3-2fa__input::placeholder {
	font-weight: var(--v3-fw-regular);
	letter-spacing: 0.32em;
}

.v3-2fa__input:focus-visible {
	outline: 2px solid var(--v3-orange-500);
	outline-offset: 2px;
}

.v3-2fa__input.is-error,
.v3-2fa__field .v3-input.is-error { border-color: var(--v3-error-500); }

.v3-2fa__error {
	margin: 0;
	color: var(--v3-error-600);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	line-height: var(--v3-lh-normal);
	text-align: center;
}

/* ---- the two dialogs on الحساب --------------------------------------- */

/* A footer, which the balance and plans dialogs do not have: both of these end
   in an action rather than in their content. */
.v3-modal__foot {
	flex: 0 0 auto;
	display: flex;
	flex-wrap: wrap;
	gap: var(--v3-space-3);
	padding: 0 var(--v3-space-7) var(--v3-space-7);
}

/* Same rule as the dialog's own actions row, and for the same reason: sized by
   the labels, wrapping rather than clipping when they do not fit. */
.v3-modal__foot > * { flex: 1 1 auto; }

.v3-modal--twofactor .v3-modal__dialog,
.v3-modal--backupcodes .v3-modal__dialog { width: min(520px, 100%); }

.v3-2fa__lead {
	margin: 0;
	color: var(--v3-text-primary);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-normal);
	text-align: center;
}

/* THREE STEPS, NOT THREE CARDS. v2 lays them out as a Bootstrap row of equal
   cards, which on a phone stacks into three tall boxes with one sentence in
   each. A numbered list says the same thing and says that the order matters. */
.v3-2fa__steps {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.v3-2fa__step {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	align-items: center;
	gap: var(--v3-space-3);
}

.v3-2fa__step-n {
	display: grid;
	place-items: center;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: var(--v3-bg-green);
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	font-weight: var(--v3-fw-semibold);
	line-height: 1;
}

.v3-2fa__step-text {
	color: var(--v3-text-primary);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	line-height: var(--v3-lh-normal);
}

/* The QR spans both columns under its own step, so it lines up with the text
   rather than squeezing into the number's column. */
.v3-2fa__step--qr { grid-template-areas: "n t" ". q"; }
.v3-2fa__step--qr .v3-2fa__step-n { grid-area: n; }
.v3-2fa__step--qr .v3-2fa__step-text { grid-area: t; }

.v3-2fa__qr {
	grid-area: q;
	display: block;
	width: 160px;
	height: 160px;
	margin-top: var(--v3-space-3);
	border-radius: var(--v3-radius-md);
	background: var(--v3-white);
}

.v3-2fa__entry {
	display: flex;
	flex-direction: column;
	gap: var(--v3-space-2);
}

/* The warning above the codes. Not .v3-dialog__note: that one is the block
   popup's orange strip, and this is an error the way v2 had it. */
.v3-2fa__warn {
	display: flex;
	align-items: flex-start;
	gap: var(--v3-space-2);
	margin: 0;
	padding: var(--v3-space-3) var(--v3-space-4);
	border: 1px solid var(--v3-error-500);
	border-radius: var(--v3-radius-md);
	background: var(--v3-bg-error);
	color: var(--v3-error-700);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	line-height: var(--v3-lh-normal);
}

.v3-2fa__warn i {
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	margin-top: 2px;
	background: var(--v3-error-700);
	-webkit-mask: url("/img/v3/game/alert.svg") no-repeat center / contain;
	mask: url("/img/v3/game/alert.svg") no-repeat center / contain;
}

/* Two columns of codes, which is what v2 has and what ten of them want. */
.v3-2fa__codes {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--v3-space-3);
}

/* A code is a value to copy, so it is monospaced, LTR and selectable — and it
   is NOT an input, which is what v2 makes it. There is nothing to type. */
.v3-2fa__code {
	direction: ltr;
	padding: 12px var(--v3-space-3);
	border: 1px solid var(--v3-border-green-off);
	border-radius: var(--v3-radius-md);
	background: var(--v3-bg-page);
	color: var(--v3-text-primary);
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: var(--v3-fs-body);
	letter-spacing: 0.08em;
	text-align: center;
	-webkit-user-select: all;   /* Safari, iOS Safari */
	user-select: all;
}

/* A spent code, struck through. The colour alone would not carry it. */
.v3-2fa__code.is-used {
	border-color: var(--v3-disabled-border);
	background: var(--v3-disabled-bg);
	color: var(--v3-disabled-fg);
	text-decoration: line-through;
}

@media (max-width: 600px) {
	.v3-modal__foot { padding: 0 var(--v3-space-5) var(--v3-space-5); }
	.v3-2fa__qr { width: 140px; height: 140px; }
	.v3-2fa__codes { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   "ضع هاتفك في الوضع الأفقي" — Figma 7227:12061.

   The two boards are landscape-only, so this is what a phone held upright
   gets. It is the badged-dialog shape the rest of v3 uses — a circle
   overhanging the panel's top edge, then title, picture, message, action —
   but DARK: it sits over a board, not over the page ground.

   MDB SHOWS AND HIDES IT, unchanged; see the note in the partial. So the
   rules below have to beat MDB's own .modal-content, which is white with a
   border and a radius of its own — hence the doubled class on the panel.
   ========================================================================== */

.v3-pw .modal-dialog {
	/* 282 at 375, which is the frame the design is drawn on. */
	width: min(282px, calc(100% - 32px));
	max-width: none;
	margin: 0 auto;
}

.v3-pw__panel {
	/* POINTER EVENTS BACK ON, and this is the cost of dropping .modal-content.

	   Bootstrap puts `pointer-events: none` on .modal-dialog so a click on the
	   sheet around the panel reaches the backdrop, and restores `auto` on
	   .modal-content. Removing that class to escape overwrites.css's
	   `background !important` took the restore with it, and the whole dialog
	   went click-through — it looked perfect and خروج did nothing.

	   One class was carrying two unrelated jobs; only one of them was the one
	   being removed. */
	pointer-events: auto;

	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	/* 40 top / 20 bottom / 45 each side — 7227:12062 inside a 282 x 226 panel */
	padding: 40px 45px 20px;
	border: 0;
	border-radius: var(--v3-radius-lg);
	background: var(--v3-bg-green);
	box-shadow: 0 8px 32px 0 rgba(0, 0, 0, .35);
	/* the badge hangs over the top edge */
	overflow: visible;
	color: var(--v3-text-inverse);
	text-align: center;
}

/* 54 square at y=-27: exactly half of it outside, unlike .v3-dialog__badge,
   which Figma hangs by a different fraction. */
.v3-pw__badge {
	position: absolute;
	top: -27px;
	left: 50%;
	transform: translateX(-50%);
	display: grid;
	place-items: center;
	width: 54px;
	height: 54px;
	border-radius: 50%;
	background: var(--v3-orange-500);
}

.v3-pw__badge::before {
	content: "";
	width: 24px;
	height: 24px;
	background: var(--v3-text-inverse);
	-webkit-mask: url("/img/v3/game/alert.svg") no-repeat center / contain;
	mask: url("/img/v3/game/alert.svg") no-repeat center / contain;
}

.v3-pw__title {
	margin: 0;
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h5);          /* 20 in a 24 box */
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
}

/* ---- the picture ------------------------------------------------------- */

.v3-pw__rotate {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 2px;
	margin-top: 14px;                    /* 38 - 24 */
	height: 48px;
}

.v3-pw__plate {
	display: grid;
	place-items: center;
	width: 97px;
	height: 48px;
	flex: 0 0 auto;
	border-radius: var(--v3-radius-md);
	background: var(--v3-bg-page);
}

.v3-pw__plate::before {
	content: "";
	width: 24px;
	height: 24px;
	background: var(--v3-green-900);
	-webkit-mask: url("/img/v3/game/rotate-phone.svg") no-repeat center / contain;
	mask: url("/img/v3/game/rotate-phone.svg") no-repeat center / contain;
}

/* One asset, ROTATED — the pair is the same arc turned about the phone, not a
   reflection of it. Mirroring put both heads at the same end and the two read as
   brackets around the phone; turning one through half a circle puts the left
   head at the top and the right head at the bottom, which is what makes them a
   rotation.

   Taller and narrower than before, because the arc itself now is: 26x46 against
   the asset's own 32x48 leaves the stroke room without letterboxing it. */
.v3-pw__arrow {
	width: 26px;
	height: 46px;
	flex: 0 0 auto;
	background: var(--v3-green-050);
	-webkit-mask: url("/img/v3/game/rotate-arrow.svg") no-repeat center / contain;
	mask: url("/img/v3/game/rotate-arrow.svg") no-repeat center / contain;
}

/* RTL renders the first child rightmost, so --start is the RIGHT-hand arrow and
   --end the left. The asset is drawn as the LEFT one — bulging left, head at the
   top — so the left keeps it untouched and the right is that same shape turned
   through half a circle. No vertical offsets: the design sits the two level. */
.v3-pw__arrow--start { transform: rotate(180deg); }

.v3-pw__message {
	margin: 14px 0 0;                    /* 100 - 86 */
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);     /* 14 in a 16 box */
	font-weight: var(--v3-fw-medium);
	line-height: var(--v3-lh-auto);
}

/* ---- the way on, and the way out --------------------------------------- */

.v3-pw__actions {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 8px;
	width: 100%;
	margin-top: 14px;                    /* 130 - 116 */
}

/* The design's button says حسنًا; this one says خروج and goes to "/" — see
   the note in the partial. It is a link rather than a button because it
   navigates, and .v3-btn styles either. */
.v3-pw__leave { width: 100%; }

.v3-pw__leave:link, .v3-pw__leave:visited,
.v3-pw__leave:hover, .v3-pw__leave:focus, .v3-pw__leave:active {
	color: var(--v3-text-inverse);
	text-decoration: none;
}

/* ==========================================================================
   The sponsor strip — Figma 11143:13021 (trivia) / 8672:16648 (وصلها)

   The same pill on both boards: a dark teal bar carrying "برعاية" and the
   sponsor's logo, sized to the column it sits in. Figma draws it with the
   button's two shine leaves, so it is built from the same parts as .v3-btn —
   but it is a <div>, not a button, with no hover, no pointer and nothing to
   focus. §7.5 asks for an ad that cannot be mistaken for a control; the shape
   is the design's, the inertness is the rule's.

   EVERYTHING SCALES FROM ONE NUMBER. --sponsor-h is set per surface and the
   type, the padding, the gap and the shine are all fractions of it, because the
   two boards size their columns completely differently — the trivia rail is a
   container query, وصلها's board column is not — and duplicating six values
   across both was six chances to have them disagree.

   #13585a is the sponsor's own teal, not one of ours: it is the ground their
   logo was designed against, and none of the v3 greens is close enough to
   borrow without dulling the mark.
   ========================================================================== */

.v3-sponsor {
	--sponsor-h: 56px;                   /* every surface overrides this */

	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: .6em;
	width: 100%;
	height: var(--sponsor-h);
	padding-inline: 1.2em;
	/* A ROUNDED RECTANGLE, not the pill this used to draw. 15.2 of the 74 the
	   dock pill is drawn at, read off 9422:33303's corner: the arc meets the
	   straight edge 15 in, where a pill's would meet it at 37. */
	border-radius: calc(var(--sponsor-h) * .205);
	background: #13585a;
	box-shadow: 0 4px 8px 0 rgba(0, 0, 0, .18);
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: calc(var(--sponsor-h) * .3);
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	white-space: nowrap;
	overflow: hidden;
	/* it is a picture of a sponsor, not something to drag, select or press */
	cursor: default;
	-webkit-user-select: none;   /* Safari, iOS Safari */
	user-select: none;
}

/* 92%, not 100%: the export already carries its own margin inside the 65x36
   box, and filling the pill edge to edge crowds the shine. */
.v3-sponsor__logo {
	display: block;
	width: auto;
	height: 92%;
}

/* The same two leaves .v3-btn wears — same art, and the same asymmetry, one
   long arc and one short — but at THE SPONSOR'S OWN numbers, not the button's.
   Taking the button's fractions drew them at roughly twice the size: 39.7 x
   31.8 where 9422:33303 draws 18.5 x 10.09, which is what turned a fine
   highlight into a grey smear across the corner.

   Every number below is that node's, over the 74 it is drawn at. The SVGs
   carry preserveAspectRatio="none", so giving them the drawn box gives the
   drawn shape — the right-hand arc is flatter here than on a button, and that
   is the design, not a stretch. */
.v3-sponsor::before,
.v3-sponsor::after {
	content: "";
	position: absolute;
	pointer-events: none;
	background-repeat: no-repeat;
	background-size: 100% 100%;
}

.v3-sponsor::after {
	top: calc(var(--sponsor-h) * .1364);      /* 10.09 */
	right: calc(var(--sponsor-h) * .2104);    /* 201.57 - (167.5 + 18.5) */
	width: calc(var(--sponsor-h) * .25);      /* 18.5  */
	height: calc(var(--sponsor-h) * .1364);   /* 10.09 */
	background-image: url("/img/v3/btn-shine-right.svg");
}

/* MIRRORED, like .v3-btn::before is. btn-shine-left.svg is the same leaf as the
   right one drawn small, and the button flips it — without the flip it curves
   the wrong way and the two ends of the pill do not read as one highlight.
   Copying the geometry and not the transform is exactly what went wrong here.

   It also sits FURTHER IN than the right one — 24 from the edge against 15.6 —
   which is the design's asymmetry and not a mistake in it. */
.v3-sponsor::before {
	top: calc(var(--sponsor-h) * .1352);      /* 10.005 */
	left: calc(var(--sponsor-h) * .3243);     /* 23.996 */
	width: calc(var(--sponsor-h) * .1258);    /*  9.310 */
	height: calc(var(--sponsor-h) * .0921);   /*  6.814 */
	background-image: url("/img/v3/btn-shine-left.svg");
	transform: scaleX(-1);
}

/* ==========================================================================
   "فئات جديدة" — the latest-categories pop-up

   v2 laid this out as two halves: copy and a CTA on one side, the six cards on
   the other, wrapping to three-per-row on desktop and turning into a horizontal
   swipe on a phone. The v3 dialog already owns its head and foot, so the copy
   goes under the title and the CTA into the footer slot, and the body is just
   the cards — which leaves them the full width to be legible in.

   The phone treatment is v2's and is kept: the grid becomes one scrolling row
   rather than a tall column, so the dialog never grows past the screen and the
   cards stay big enough to recognise.
   ========================================================================== */

.v3-modal--latest .v3-modal__dialog { width: min(760px, 100%); }

.v3-latest__lead {
	margin: 0 0 var(--v3-space-5);
	color: var(--v3-text-secondary);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);
	font-weight: var(--v3-fw-medium);
	line-height: 1.7;
	text-align: center;
}

.v3-latest__grid {
	flex: 0 0 auto;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--v3-space-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.v3-latest__card {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	border-radius: 16px;
	background: var(--v3-bg-surface);
	box-shadow: 0 2px 8px 0 rgba(0, 0, 0, .08);
	overflow: hidden;
	text-decoration: none;
	transition: transform 160ms ease, box-shadow 160ms ease;
}

/* MDB's a:hover is (0,1,1) and a bare class is (0,1,0), so an anchor that
   names no colour of its own goes blue the moment you point at it. Saying it
   on the states is the guard — scripts/v3-audit.js check 1 is what caught
   this card without one. */
.v3-latest__card:link,
.v3-latest__card:visited,
.v3-latest__card:hover,
.v3-latest__card:focus,
.v3-latest__card:active { color: var(--v3-green-900); }

.v3-latest__card:hover {
	transform: translateY(-2px);
	box-shadow: 0 6px 16px 0 rgba(0, 0, 0, .14);
}

/* The image is the card's whole top; the name sits on an opaque strip under it,
   which is how .v3-sg__card does it on /start-game — a name over artwork needs
   a scrim, and a name under it needs nothing. */
.v3-latest__media {
	position: relative;
	display: block;
	width: 100%;
	min-height: 0;
	aspect-ratio: 220 / 253.5;
	background: var(--v3-green-100);
}

.v3-latest__img {
	display: block;
	width: 100%;
	height: 100%;
	min-height: 0;
	object-fit: cover;
}

.v3-latest__badge {
	position: absolute;
	inset-block-start: 6px;
	inset-inline-end: 6px;
	z-index: 2;
	padding: 3px 10px;
	border-radius: var(--v3-radius-pill);
	background: var(--v3-green-800);
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
}

/* مجددة is the rarer, more interesting state — an established category that has
   just grown — so it takes the brand orange and جديدة stays green. */
.v3-latest__badge--renewed { background: var(--v3-orange-500); }

.v3-latest__subtitle {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	z-index: 2;
	padding: 4px 12px;
	background: var(--v3-bg-brand);
	color: var(--v3-text-inverse);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-caption);
	font-weight: var(--v3-fw-semibold);
	line-height: var(--v3-lh-auto);
	text-align: center;
}

.v3-latest__name {
	display: grid;
	place-items: center;
	flex: 1 0 auto;
	min-height: 56px;
	padding: 8px 14px;
	color: var(--v3-green-900);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-title);
	font-weight: var(--v3-fw-bold);
	line-height: var(--v3-lh-auto);
	text-align: center;
}


@media (max-width: 900px) {
	.v3-latest__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-height: 960px) {
	.v3-modal--latest .v3-modal__body { gap: var(--v3-space-4); padding: var(--v3-space-6); }
	.v3-modal--latest .v3-modal__foot { padding: 0 var(--v3-space-6) var(--v3-space-6); }
	.v3-latest__lead { margin-bottom: var(--v3-space-4); }
	.v3-latest__grid { gap: var(--v3-space-4); }
	.v3-latest__media { aspect-ratio: 1 / 1; }
	.v3-latest__name { min-height: 46px; font-size: var(--v3-fs-body); }
}

/* v2's phone answer: one scrolling row rather than a six-card column, so the
   dialog stays inside the screen and the cards keep their size.

   THE SECOND QUERY IS LANDSCAPE. A phone turned sideways is 844 wide and 390
   tall, so the width queries above all miss it and it gets the desktop grid
   in 390px of height. Short is the same problem narrow is — there is no room
   for two rows — and it has the same answer, so the row treatment is keyed on
   either. 620 clears a landscape phone and stays under the shortest laptop
   the height query above already handles. */
@media (max-width: 600px), (max-height: 620px) {
	.v3-latest__grid {
		display: flex;
		gap: var(--v3-space-4);
		overflow-x: auto;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;
	}
	.v3-latest__grid::-webkit-scrollbar { display: none; }
	.v3-latest__item { flex: 0 0 auto; width: 148px; }
	.v3-latest__name { min-height: 44px; font-size: var(--v3-fs-body); }
}

@media (max-height: 620px) {
	.v3-latest__item { width: 128px; }
	.v3-latest__name { min-height: 38px; }
}

/* ==========================================================================
   The announcement pop-up — تحداني × بيڤو

   THE ONE DIALOG THAT DOES NOT WEAR THE HOUSE CHROME. Every other v3 modal is
   a green bar over a cream body, which is the system talking. This one is the
   partner talking, so it takes their surface: #13585a is the teal bivo.svg is
   drawn for — the same ground the in-game sponsor pill uses — and #88e8e8 is
   the mark's own colour, sampled from the export rather than guessed.

   Everything here is scoped under .v3-modal--announce, so the component is
   untouched and the campaign can be deleted in one piece.
   ========================================================================== */

.v3-modal--announce {
	--ann-ground: #13585a;               /* the teal the mark is drawn for */
	--ann-deep:   #0d3f41;               /* the same, further back */
	--ann-mark:   #88e8e8;               /* sampled from bivo.svg */
}

/* Narrower than the shared 1040: a mark and two short lines do not want a
   1040 dialog, and the copy reads badly at that measure. */
.v3-modal--announce .v3-modal__dialog {
	width: min(480px, 100%);

	/* One surface, lit from behind the mark. The gradient is what stops a flat
	   dark card reading as a slab — the light sits where the logo does. */
	background:
		radial-gradient(120% 90% at 50% 8%, rgba(136, 232, 232, .16) 0%, rgba(136, 232, 232, 0) 60%),
		linear-gradient(180deg, var(--ann-ground) 0%, var(--ann-deep) 100%);
	box-shadow: 0 24px 60px 0 rgba(4, 40, 42, .45);
}

/* THE BAR GOES. It is a band of a different green across the top of a teal
   card — the one thing that would still look borrowed. The head keeps its
   height so the close button lands where it always does. */
.v3-modal--announce .v3-modal__head {
	background: none;
	padding-inline: var(--v3-space-6);
}

.v3-modal--announce .v3-modal__title {
	color: var(--v3-white);
	font-weight: var(--v3-fw-bold);
}

/* تحداني's mark, beside a title that names both. */
.v3-modal--announce .v3-modal__head-icon { background: var(--v3-white); }

/* A cream disc is a hole punched in a dark card. Glass instead, and the × in
   the mark's colour so the two ends of the dialog agree. */
.v3-modal--announce .v3-modal__close {
	background: rgba(255, 255, 255, .12);
}
.v3-modal--announce .v3-modal__close::before { background: var(--ann-mark); }
.v3-modal--announce .v3-modal__close:hover { background: rgba(255, 255, 255, .22); }

.v3-modal--announce .v3-modal__body {
	align-items: center;
	gap: 0;
	padding-top: var(--v3-space-3);
}

/* NO PLATE ANY MORE. The card is already the ground the mark wants, so the
   logo sits straight on it — which is the whole reason this dialog changed
   colour rather than gaining a coloured panel inside a cream one. */
.v3-announce__logo {
	display: block;
	width: min(208px, 62%);
	height: auto;
	margin: var(--v3-space-4) 0 var(--v3-space-6);
}

.v3-announce__lead {
	margin: 0;
	color: var(--v3-white);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-h5);
	font-weight: var(--v3-fw-bold);
	line-height: 1.6;
	text-align: center;
}

.v3-announce__text {
	margin: var(--v3-space-3) 0 0;
	/* The mark's colour at a quarter strength — a tint of the same light rather
	   than a second colour. */
	color: rgba(224, 250, 250, .78);
	font-family: var(--v3-font);
	font-size: var(--v3-fs-body);
	font-weight: var(--v3-fw-medium);
	line-height: 1.75;
	text-align: center;
}

/* THE ACTION IS THE MARK'S OWN COLOUR, which is the loudest thing on a dark
   card and the only place the brand orange would have fought the teal. */
.v3-modal--announce .v3-modal__foot .v3-btn {
	background: var(--ann-mark);
	color: #0b3739;
	font-weight: var(--v3-fw-bold);
	box-shadow: 0 10px 24px 0 rgba(136, 232, 232, .22);
}

.v3-modal--announce .v3-modal__foot .v3-btn:hover {
	background: #9ff2f2;
	color: #0b3739;
}

/* .v3-btn's two shine leaves are cream at 70%, which on #88e8e8 is a smudge
   rather than a highlight — the button is lighter than the shine. */
.v3-modal--announce .v3-modal__foot .v3-btn::before,
.v3-modal--announce .v3-modal__foot .v3-btn::after { display: none; }

@media (max-height: 620px) {
	.v3-announce__logo { width: min(160px, 48%); margin-block: var(--v3-space-2) var(--v3-space-4); }
	.v3-announce__lead { font-size: var(--v3-fs-body); }
	.v3-announce__text { font-size: var(--v3-fs-caption); }
}
