/**
 * Tran Atomic Builder — Frontend content styles
 * ============================================================================
 * WYSIWYG CONTRACT: this file defines the geometry of section CONTENT (the
 * image frame, aspect-ratio, fit and focus behaviour). It is loaded on BOTH
 * surfaces:
 *   - the public frontend (so the published page renders correctly), and
 *   - the builder canvas (so the editor preview matches the frontend exactly).
 *
 * Anything that is editor-only (selection outlines, quick actions, hover
 * controls, the dark panel chrome) lives in builder.css, NOT here. Keeping the
 * pure content geometry in one shared file is what guarantees that what the
 * user sees in the editor is what they get on the page.
 *
 * SHARED CONTENT CLASS: both the frontend frame and the editor canvas wrap
 * carry the class .tab-image-frame. The geometry rules below target that one
 * class, so a single ruleset drives identical geometry in both contexts and
 * the two surfaces cannot drift apart. The context-specific classes
 * (.tran-atomic-image-frame on the frontend, .fab-image-wrap in the editor)
 * remain for markup identity and JS hooks but are no longer used for geometry.
 * ========================================================================== */

/* --- Luxury design tokens (LUXURY-DESIGN-TOKEN-FOUNDATION) ---------------- *
 * One source of truth for the OUTPUT's premium visual language: colour,
 * typography, spacing, radius and motion. Scoped to .tran-atomic-section so the
 * tokens ride on the builder's OWN content (this class is present on BOTH the
 * canvas and the frontend, so the editor preview and the published page stay
 * identical) and never leak onto the host theme. The theme-robust box contract
 * below is unchanged — the WRAPPER still pins only geometry; these tokens dress
 * only the plugin's own content classes, so the host theme keeps its page while
 * builder sections gain a deliberate, expensive identity. Editor chrome
 * (builder.css, the #2271b1 admin accent) intentionally follows later: this
 * phase leads with the output. */
.tran-atomic-section {
	/* Colour — disciplined, ink-led neutrals (supersedes scattered Tailwind greys) */
	--fab-ink:          #14181c; /* near-black, a touch warm — headings */
	--fab-text:         #353b42; /* body copy */
	--fab-muted:        #6b7280; /* secondary / captions */
	--fab-border:       #e6e7ea; /* hairlines + dividers */
	--fab-surface:      #f7f8f8; /* soft panels (CTA band) */
	--fab-accent:       #14181c; /* ONE accent: ink — luxe, not software-blue */
	--fab-accent-hover: #3a4048;
	--fab-on-accent:    #ffffff;

	/* Typography — the primary branding signal */
	--fab-font-display:    "Hoefler Text", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
	--fab-tracking-tight:  -0.012em; /* large display serif */
	--fab-tracking-label:   0.085em; /* uppercase utility labels */
	--fab-leading-tight:    1.16;
	--fab-leading-body:     1.65;
	--fab-weight-display:   600;

	/* Spacing — a small coherent rhythm */
	--fab-space-1: 4px;
	--fab-space-2: 8px;
	--fab-space-3: 16px;
	--fab-space-4: 24px;
	--fab-space-5: 40px;
	--fab-space-6: 56px;

	/* Radius — precise, not pillowy */
	--fab-radius:    3px;
	--fab-radius-lg: 6px;

	/* Motion — weighted, calm ease-out */
	--fab-ease: cubic-bezier(0.2, 0, 0, 1);
	--fab-dur:  240ms;
}

/* --- Sections wrapper: the plugin's geometry scope ----------------------- *
 * THEME-ROBUST: all sections render inside .tran-atomic-sections (mirrors the
 * builder's .fab-canvas-inner). This gives the plugin a reliable box scope on
 * the frontend so an opinionated theme cannot reshape the section column via
 * rules targeting bare children of .entry-content (e.g. `.entry-content > *
 * { max-width: 50ch }`, float/clear, or display resets).
 *
 * We pin ONLY the box contract here — box-sizing + a predictable block flow —
 * NOT typography, NOT colour, NOT the outer page width. The doubled-class
 * selector (0,2,0) beats `.entry-content > div` (0,1,1) without !important and
 * without a global reset. Direct children get box-sizing so a theme's
 * border/padding model can't change a section's effective width, and their
 * horizontal margins are neutralised so the section column is the plugin's to
 * own; vertical spacing (margin-top/bottom) is left to each section + theme. */
.tran-atomic-sections.tran-atomic-sections {
	box-sizing: border-box;
	width:      100%;
	max-width:  100%;
	/* establish an independent block formatting context so theme float/clear
	   rules in surrounding content cannot bleed into the section column */
	display:    flow-root;
}
.tran-atomic-sections.tran-atomic-sections > * {
	box-sizing:    border-box;
	max-width:     100%;
	margin-left:   0;
	margin-right:  0;
}

/* DESIGN-CONTROLS (v0.5.26): per-section design wrapper. Transparent by
 * default — an unstyled section is visually identical to before. It carries the
 * optional inline background-color + padding-top/bottom set in the Inspector,
 * using the SAME inline style string the canvas uses (WYSIWYG parity). The type
 * markup now nests one level deeper, so we mirror the box-contract onto the
 * wrapper's direct children to keep theme float/clear/margins from bleeding into
 * the section column. */
.tran-atomic-section {
	box-sizing: border-box;
}
.tran-atomic-sections.tran-atomic-sections .tran-atomic-section {
	width:     100%;
	max-width: 100%;
}

/* LIVE-PARITY-1 — inter-section vertical rhythm (BUILDER-owned, shared layer).
 * The builder wraps every section in ONE .tran-atomic-sections div, which
 * isolates them from the theme's flow spacing: a theme's `> * + *` / block-gap
 * lands on the wrapper, not on the .tran-atomic-section children inside it. So
 * without this rule published sections collapse together (0 gap) while the
 * editor — which spaces sections via its own .fab-section-block chrome (a ~40px
 * action-bar reserve + a 20px margin ≈ a ~60px visual gap) — looks fine. The
 * builder therefore owns the rhythm between its OWN sections; we set it once
 * here, in the shared stylesheet, with a token (~ the editor's visual gap). The
 * owl selector (+ sibling) adds NO leading/trailing margin, so it never fights
 * the theme's spacing around the whole block. It targets the FRONT-END wrapper
 * only; the editor canvas has no .tran-atomic-sections wrapper (its sections sit
 * in .fab-section-block), so there is no double spacing there. Tokenised so a
 * future global style can tune it. */
.tran-atomic-sections.tran-atomic-sections > .tran-atomic-section + .tran-atomic-section {
	margin-top: var(--fab-space-6);
}
.tran-atomic-sections.tran-atomic-sections .tran-atomic-section > * {
	box-sizing:   border-box;
	max-width:    100%;
	margin-left:  0;
	margin-right: 0;
}

/* --- WYSIWYG body-width parity (v0.3.5) ---------------------------------- *
 * The builder canvas caps the text-section body copy to a 65ch readability
 * measure (see builder.css, "Prose line-length limit"). Mirror that EXACT cap
 * here so the published body width matches the editor instead of running the
 * full content column. Scoped to the plugin's own body paragraph only — this
 * is NOT a global theme-paragraph rule. The headline is deliberately NOT
 * capped (broad headline over readable body = the intended hierarchy).
 *
 * Doubled-class specificity (0,3,0) is required because the body <p> is a
 * direct child of .tran-atomic-sections and the box-contract rule above
 * already sets max-width:100% on every child (0,2,0). We override ONLY
 * max-width; box-sizing and the margin reset from that rule still apply. On
 * narrow viewports the paragraph fills its container as usual (max-width only
 * caps, it never forces width), so this adds no mobile overflow. */
.tran-atomic-sections.tran-atomic-sections .tran-atomic-intro {
	max-width: 65ch;
}

/* --- Editorial type: the builder's own headings + body ------------------- *
 * Output-first premium typography applied ONLY to the plugin's content classes
 * (present on canvas + frontend → WYSIWYG-safe). Headings take a refined serif
 * display stack with tight tracking and leading for an expensive, editorial
 * voice; we deliberately set NO font-size so each section keeps the theme's
 * responsive heading scale — we refine the *quality* of the type, not its size.
 * Body keeps the theme's (sans) family for contrast and just gains calmer
 * leading and a considered text colour. All values flow from the token layer.
 *
 * TYPOGRAPHY SOURCE OF TRUTH (decision, v0.5.88): headline/display *quality*
 * (family, weight, tracking, leading, colour) is BUILDER-owned via the shared
 * token layer and is identical on canvas + front end. Headline *size / scale*
 * is THEME-owned on the front end — a deliberate product choice that keeps the
 * builder a theme-friendly content layer (it integrates through the_content and
 * already inherits the theme's body family and content width). Do NOT add a
 * font-size here to "match the editor": that would override every theme's
 * heading scale on published pages, change live output, and make the builder
 * less theme-friendly. The editor canvas uses a neutral stand-in size (see
 * builder.css) only because it has no theme — that gap is intentional theme
 * context, not drift. */
.tran-atomic-headline,
.tran-atomic-subheadline,
.tran-atomic-cta-headline {
	font-family:    var(--fab-font-display);
	font-weight:    var(--fab-weight-display);
	letter-spacing: var(--fab-tracking-tight);
	line-height:    var(--fab-leading-tight);
	color:          var(--fab-ink);
}
.tran-atomic-intro {
	line-height: var(--fab-leading-body);
	color:       var(--fab-text);
}

/* --- Hero presence (HERO-PRESENCE-1) -------------------------------------- *
 * The hero is the page's opening statement, so — unlike an inline heading whose
 * SIZE is intentionally theme-owned (see the TYPOGRAPHY SOURCE OF TRUTH note
 * above) — the builder owns the HERO TITLE's presence. This is the deliberate,
 * documented exception to that decision: it is scoped STRICTLY to
 * .tran-atomic-section--hero (a registry-validated type modifier on the shared
 * section wrapper), so no other section and no theme heading is affected, and
 * theme-friendliness elsewhere is untouched. Sizing is fluid clamp() —
 * commanding on desktop, controlled on mobile, with NO media queries and NO
 * theme override beyond the hero itself. It lives in the shared stylesheet, so
 * the editor canvas and the published page render the hero identically. The
 * subtitle is set a touch lighter to let the title lead. (Higher specificity
 * than the editor stand-in, so the canvas hero title is commanding too.) */
.tran-atomic-section--hero .tran-atomic-headline {
	font-size:   clamp(2.25rem, 1.4rem + 3.2vw, 3.75rem);
	line-height: 1.08;
	margin:      0 0 var(--fab-space-2);
}
.tran-atomic-section--hero .tran-atomic-subheadline {
	font-size:   clamp(1.1rem, 0.95rem + 0.6vw, 1.4rem);
	font-weight: 400;
	line-height: 1.4;
	margin:      0;
}

/* --- Block + caption ----------------------------------------------------- *
 * THEME-OWNERSHIP CONTRACT: the plugin owns the image frame GEOMETRY; the
 * theme may style the surrounding page chrome (typography, colours, the
 * .entry-content container width, and the block's outer MARGIN) but must not
 * be able to reshape the frame itself. Every geometry declaration below is
 * therefore scoped under .tran-atomic-image-block (specificity 0,2,0 for frame
 * rules, 0,1,0 for the block box) so that a Bootstrap-style content reset such
 * as `.entry-content img { height:auto }` or `.entry-content div { width:auto;
 * overflow:visible }` (specificity 0,1,1) cannot win. This is done with
 * specificity only — no !important, no global reset, no theme-specific hack —
 * and the same .tran-atomic-image-block wrapper is present on BOTH the editor
 * canvas and the frontend, so WYSIWYG parity is preserved. The fixed-ratio
 * and 'original' overrides further down are 0,2,1+ and stay above this base. */
.tran-atomic-image-block {
	margin: 24px 0;          /* outer spacing = page chrome; theme may restyle */
	width:  100%;
}

/* IMAGE LAYOUT CONTRACT — block box identity.
 * The block element is a <figure>, so generic theme/UA figure defaults can
 * change its box behaviour (figure{margin:1em 40px}, display:table/inline-block,
 * padding, box-sizing) and indirectly the frame inside it. We pin the box
 * identity on a doubled-class selector (0,2,0) so it beats `.entry-content
 * figure` (0,1,1) and plain `figure` (0,0,1) — but we deliberately do NOT pin
 * margin here, so the theme keeps control of outer spacing (page chrome). This
 * owns only display/box-sizing/padding/max-width: the minimum needed for a
 * predictable box, no layout system, no global reset. */
.tran-atomic-image-block.tran-atomic-image-block {
	display:    block;
	box-sizing: border-box;
	padding:    0;
	max-width:  100%;
}

.tran-atomic-image-block .tran-atomic-image-caption {
	font-size:      13px;
	color:          var(--fab-muted);
	margin:         var(--fab-space-2) 0 0;
	padding:        0 var(--fab-space-2);
	display:        block;
	text-align:     center;
	letter-spacing: 0.01em;
	line-height:    var(--fab-leading-body);
}

/* --- The frame: neutral mat, rounded, clips the image --------------------
 * .tab-image-frame is the SINGLE shared content class present on both the
 * frontend frame and the editor canvas wrap (and the JS-created wrap). Scoped
 * under .tran-atomic-image-block so the theme cannot reshape it. overflow:
 * hidden is what clips the zoomed image to the frame — if a theme reset made
 * it visible the scaled image would spill out, so it must be plugin-owned. */
.tran-atomic-image-block .tab-image-frame {
	width:           100%;
	max-height:      420px;          /* calm cap for 'original' */
	border-radius:   var(--fab-radius-lg);
	overflow:        hidden;
	background:      #f1f3f5;         /* neutral mat behind contained images */
	display:         flex;
	align-items:     center;
	justify-content: center;
}

/* --- The image fills the frame; fit + position come from data-* ---------- *
 * The width/height live on the block-scoped selector below (specificity
 * 0,2,0) so a Bootstrap-based theme's content reset — e.g.
 * `.entry-content img { height: auto }` (0,1,1) — cannot shrink the image
 * back to auto height. Without this the frontend image renders taller than
 * its frame and object-fit:cover crops a different region than the editor,
 * which loads no theme CSS. The 'original'-ratio rules further down carry
 * even higher specificity, so their intentional height:auto still wins. */
.tran-atomic-image-block .tran-atomic-image {
	width:      100%;
	height:     100%;
	display:    block;
	object-fit: cover; /* default; overridden per data-fit below */
}

/* Optional link wrapper must not change layout — block-scoped so a theme's
   `.entry-content a { display:inline }` cannot collapse the fill wrapper. */
.tran-atomic-image-block .tran-atomic-image-link {
	display: block;
	width:   100%;
	height:  100%;
}

/* --- Fit mode: Fill (cover) vs Fit (contain) ---------------------------- */
.tran-atomic-image-block[data-fit="contain"] .tran-atomic-image {
	object-fit: contain;
}
.tran-atomic-image-block[data-fit="cover"] .tran-atomic-image {
	object-fit: cover;
}

/* --- 'original' ratio: the image's OWN aspect ratio, shown WHOLE ---------- *
 * "Original" must mean original: the full image, never cropped, scaled down to
 * fit within the full width and a calm 420px height cap. width+height auto make
 * the <img> box take the image's natural ratio, so object-fit has nothing to
 * crop or letterbox — Fill and Fit look identical here, which is correct.
 * (Previously Fill forced width:100% + object-fit:cover, so a portrait was
 * cropped into a wide full-width band — not original.) The frame stays
 * full-width with a neutral mat; the image centres within it. */
.tran-atomic-image-block[data-ratio="original"] .tab-image-frame {
	height: auto;
}
.tran-atomic-image-block[data-ratio="original"] .tran-atomic-image {
	width:      auto;
	height:     auto;
	max-width:  100%;
	max-height: 420px;
	margin:     0 auto;
}

/* --- Fixed ratios: size FROM a stable height, derive width -------------- *
 * height + aspect-ratio (set inline on the frame) makes the browser compute
 * the width, so a 1:1 frame is a real square, not a full-width giant. The
 * box is centred; very wide ratios are capped at the canvas width. */
.tran-atomic-image-block:not([data-ratio="original"]) .tab-image-frame {
	height:     380px;
	max-height: 380px;
	width:      auto;
	max-width:  100%;
	margin:     0 auto;
}

/* --- Object-position (focus) — meaningful for cover -------------------- */
.tran-atomic-image-block[data-position="center"] .tran-atomic-image { object-position: center; }
.tran-atomic-image-block[data-position="top"]    .tran-atomic-image { object-position: top; }
.tran-atomic-image-block[data-position="bottom"] .tran-atomic-image { object-position: bottom; }
.tran-atomic-image-block[data-position="left"]   .tran-atomic-image { object-position: left; }
.tran-atomic-image-block[data-position="right"]  .tran-atomic-image { object-position: right; }

/* --- CTA banner --------------------------------------------------------- *
 * SHARED across the editor canvas and the published page (single source of
 * truth = WYSIWYG). Both surfaces carry .tran-atomic-cta, so the call-to-action
 * looks identical in the builder and on the frontend. Previously the published
 * .tran-atomic-cta had NO styling — its rules lived in the editor-only
 * builder.css and never reached the frontend, so the live banner rendered as
 * unstyled text. Pinning the banner here fixes that and removes the drift. */
.tran-atomic-cta {
	background:    var(--fab-surface);
	border:        1px solid var(--fab-border);
	border-radius: var(--fab-radius-lg);
	padding:       var(--fab-space-5) var(--fab-space-4);
	text-align:    center;
	margin:        var(--fab-space-3) 0;
}
.tran-atomic-cta .tran-atomic-cta-headline {
	/* family / tracking / leading / ink come from the shared headline rule;
	 * size + rhythm are pinned here so the CTA heading stays compact. */
	font-size:   22px;
	font-weight: var(--fab-weight-display);
	margin:      0 0 var(--fab-space-2);
}
.tran-atomic-cta .tran-atomic-cta-body {
	font-size:   14px;
	color:       var(--fab-muted);
	line-height: var(--fab-leading-body);
	margin:      0 0 var(--fab-space-3);
}
.tran-atomic-cta .tran-atomic-cta-btn {
	display:         inline-block;
	background:      var(--fab-accent);
	color:           var(--fab-on-accent);
	padding:         12px 28px;
	border-radius:   var(--fab-radius);
	font-size:       14px;
	font-weight:     600;
	letter-spacing:  0.01em;
	text-decoration: none; /* the <a> button is a button, not an underlined link */
	transition:      background var(--fab-dur) var(--fab-ease);
}
/* Interactive states for the published call-to-action LINK. Scoped to the <a>
 * so they only fire on the real frontend button; the editor renders the button
 * as an inline-editable label (a <span>), which these never touch. */
/* Hover LIGHTENS the dark button for a clearly perceptible lift. Going darker
 * (toward #000) was almost invisible against the near-black base; #374151 gives
 * an obvious state change while white text keeps a 10:1 contrast (well past AA). */
a.tran-atomic-cta-btn:hover {
	background: var(--fab-accent-hover);
}
a.tran-atomic-cta-btn:focus-visible {
	outline:        2px solid var(--fab-ink);
	outline-offset: 2px;
}

/* --- Screen-reader-only utility ----------------------------------------- *
 * Visually hidden but kept in the accessibility tree. Used by the CTA link to
 * append "(opens in a new tab)" to the accessible name when target=_blank is
 * set, without adding any visible chrome. */
.fab-sr-only {
	position:    absolute;
	width:       1px;
	height:      1px;
	padding:     0;
	margin:      -1px;
	overflow:    hidden;
	clip:        rect(0, 0, 0, 0);
	white-space: nowrap;
	border:      0;
}

/* --- COLUMNS (first layout slice, v0.5.31) ------------------------------- *
 * Two fixed text columns. The stacking is driven by a CONTAINER query on a
 * columns-ONLY wrapper, so it responds to the column component's own width —
 * which on the builder canvas is the card width, not the browser viewport.
 * That makes the canvas Mobile preview faithful. container-type lives ONLY on
 * this wrapper, never on the shared .tran-atomic-sections / .tran-atomic-section
 * wrappers, so no other section type is affected. */
.tran-atomic-columns-wrap {
	container-type: inline-size;
	width: 100%;
}
.tran-atomic-columns {
	display:     grid;
	gap:         32px;
	align-items: start;
}
/* Variant descriptor → grid template. cols-2 is user-facing in 1A; cols-3 and
 * cols-4 are RESERVED (rendered only if a section carries that variant) so
 * Phase C needs no new CSS. */
.tran-atomic-columns--cols-2 { grid-template-columns: 1fr 1fr; }
.tran-atomic-columns--cols-3 { grid-template-columns: repeat(3, 1fr); }
.tran-atomic-columns--cols-4 { grid-template-columns: repeat(4, 1fr); }
.tran-atomic-col {
	min-width: 0; /* let grid cells shrink so long words wrap instead of overflowing */
}
.tran-atomic-col > :first-child { margin-top: 0; }
.tran-atomic-col > :last-child  { margin-bottom: 0; }
.tran-atomic-col-body {
	margin: 0;
	max-width: none; /* a column is already a narrow measure; no extra cap needed */
}
/* Stacking is driven by the columns component's OWN width (container query),
 * not the viewport — so the Mobile canvas card and a real phone both stack
 * faithfully. Each variant collapses progressively. */
@container (max-width: 600px) {
	.tran-atomic-columns--cols-2 { grid-template-columns: 1fr; gap: 24px; }
}
@container (max-width: 820px) {
	.tran-atomic-columns--cols-3,
	.tran-atomic-columns--cols-4 { grid-template-columns: 1fr 1fr; gap: 24px; }
}
@container (max-width: 520px) {
	.tran-atomic-columns--cols-3,
	.tran-atomic-columns--cols-4 { grid-template-columns: 1fr; }
}

/* --- PHASE B: image slots inside columns -------------------------------- *
 * A column image fills its cell. The aspect-ratio box comes from the inline
 * style the renderer emits (4:3 in v1); fit + focal come from data-fit + the
 * inline object-position the SHARED image helper writes — so a column image
 * frames identically on the canvas and the frontend (one helper = no drift). */
.tran-atomic-col-image {
	width:         100%;
	border-radius: var(--fab-radius-lg);
	overflow:      hidden;
	background:    #f1f3f5;
	display:       block;
}
.tran-atomic-col-image .tran-atomic-image {
	width:      100%;
	height:     100%;
	display:    block;
	object-fit: cover;
}
.tran-atomic-col-image[data-fit="contain"] .tran-atomic-image { object-fit: contain; }
.tran-atomic-col-image[data-fit="cover"]   .tran-atomic-image { object-fit: cover; }

/* SECTION-DESIGN-SYSTEM-1: a dark-background section keeps readable text on the
 * front end — its content inherits the section's own light text colour, so a
 * theme's heading/link colours can't reduce readability. Matches the canvas. */
.tran-atomic-section--on-dark :is(h1,h2,h3,h4,h5,h6,p,li,blockquote) { color: inherit; }
.tran-atomic-section--on-dark a { color: inherit; }

/* SECTION-VISUAL-HIERARCHY-1: curated section "frame" treatments. Loaded on
 * BOTH the canvas and the front end (this stylesheet is shared), and the
 * matching class is emitted by ONE helper (fab_section_design_class), so the
 * editor, preview and published page render the exact same treatment with no
 * inline drift. The wrapper already has box-sizing:border-box (above), so the
 * border + padding sit INSIDE the section width — neither option can introduce
 * mobile/narrow overflow. Both treatments share a gentle radius and a
 * horizontal inset so content never touches the frame edge; the vertical
 * padding here is only a FALLBACK — when the section sets its own spacing, the
 * inline padding-top/bottom (a longhand from the style attribute) wins over
 * this shorthand, so the spacing control stays authoritative. Effects are kept
 * deliberately subtle (a hairline border / a soft shadow) so a frame reads as
 * "intentional object", not decoration. */
.tran-atomic-section--frame-outline,
.tran-atomic-section--frame-raised {
	border-radius: var(--fab-radius-lg);
	padding:       28px clamp(20px, 4vw, 32px);
}
.tran-atomic-section--frame-outline { border: 1px solid rgba(18, 24, 39, 0.12); }
.tran-atomic-section--frame-raised  { box-shadow: 0 1px 2px rgba(18, 24, 39, 0.06), 0 10px 28px rgba(18, 24, 39, 0.08); }

/* Respect reduced-motion on the published page (U-5). */
@media (prefers-reduced-motion: reduce) {
	a.tran-atomic-cta-btn {
		transition: none;
	}
}

/* =====================================================================
 * RESPONSIVE-1 (R1a) — per-breakpoint spacing overrides (D1/D3/D6).
 * A section carries .tran-atomic-section--rsp ONLY when overrides exist;
 * its inline style then emits custom properties (--fab-pt/-t/-m, --fab-pb/…)
 * instead of direct padding. These consumers own cascade + responsiveness.
 * Nested var() fallbacks ARE the desktop → tablet → mobile inheritance.
 * The media rules are guarded off the builder screen: inside the editor the
 * canvas previews devices by width, not by browser viewport — the
 * data-device mirror in builder.css is the canvas-side consumer instead.
 * Breakpoints are locked (D6): tablet ≤ 1024px, mobile ≤ 640px.
 * ===================================================================== */
.tran-atomic-section--rsp {
	padding-top:    var(--fab-pt, 0);
	padding-bottom: var(--fab-pb, 0);
}
@media (max-width: 1024px) {
	body:not(.fab-builder-screen) .tran-atomic-section--rsp {
		padding-top:    var(--fab-pt-t, var(--fab-pt, 0));
		padding-bottom: var(--fab-pb-t, var(--fab-pb, 0));
	}
}
@media (max-width: 640px) {
	body:not(.fab-builder-screen) .tran-atomic-section--rsp {
		padding-top:    var(--fab-pt-m, var(--fab-pt-t, var(--fab-pt, 0)));
		padding-bottom: var(--fab-pb-m, var(--fab-pb-t, var(--fab-pb, 0)));
	}
}
