/* ==========================================================================
   Telugu Scope — the ONE typography system.

   Everything type-related is declared here and inherited everywhere else. No
   block, template or component should declare a font-family of its own; if one
   needs a different role, it uses a token below rather than naming a family.

   Telugu needs no special handling anywhere: each stack ends in the matching
   Noto Telugu face, so a Telugu glyph falls through to it automatically while
   Latin text uses the Latin face. That is why there is deliberately no
   "Telugu font" rule in this file or any other.
   ========================================================================== */

/* --------------------------------------------------------------------------
   A metric-matched stand-in for Newsreader, so the swap does not move the page.

   Georgia is the natural fallback — a system serif, no download — but it is not
   the same SHAPE. Measured in the renderer at 100px on a real headline string:

                     advance width      ascent / descent
     Newsreader 700      3711.9            74 / 27
     Georgia    700      4182.8            92 / 22

   Georgia sets the same headline 12.7% wider and on a taller line box, so a
   headline wraps one way while Newsreader is in flight and re-wraps when it
   arrives. On the article template that measured as everything below the H1 —
   byline, standfirst, the whole layout — shifting on load: CLS 0.0017 before
   this typeface change, 0.0396 after.

   These descriptors scale Georgia to Newsreader's metrics for the duration of
   the swap. Three faces rather than one because the correct scale depends on
   weight, and a single size-adjust would fix the headline while distorting
   everything else: 400 needs 95.69%, 700 needs 88.74%, 800 needs 92.30%.

   `src: local()` only — nothing is downloaded. Where Georgia is not installed
   the face simply fails to resolve and the stack moves on, which is why real
   Georgia is still listed behind it.
   -------------------------------------------------------------------------- */
@font-face {
	font-family: 'Newsreader Fallback';
	src: local('Georgia'), local('Times New Roman');
	font-weight: 400 500;
	size-adjust: 95.69%;
	ascent-override: 74%;
	descent-override: 27%;
	line-gap-override: 0%;
}
@font-face {
	font-family: 'Newsreader Fallback';
	src: local('Georgia'), local('Times New Roman');
	font-weight: 600 700;
	size-adjust: 88.74%;
	ascent-override: 74%;
	descent-override: 27%;
	line-gap-override: 0%;
}
@font-face {
	font-family: 'Newsreader Fallback';
	src: local('Georgia'), local('Times New Roman');
	font-weight: 800 900;
	size-adjust: 92.30%;
	ascent-override: 74%;
	descent-override: 27%;
	line-gap-override: 0%;
}

:root {
	/* Type roles */
	/* v1.10.422 — Newsreader is the editorial display face for Latin, Noto Serif
	   Telugu for Telugu. Georgia stays immediately behind them as the fallback
	   that renders while Newsreader is still in flight: it is a system face, so
	   it needs no download, and it is the metric-closest serif already proven on
	   this site — it is what every headline rendered in until this version.

	   The ORDER of the first two entries is what makes Telugu work, and it is
	   not arbitrary. Newsreader carries no Telugu glyphs, so a Telugu headline
	   falls through to Noto Serif Telugu automatically while Latin text in the
	   same headline uses Newsreader. Measured on staging, a mixed headline
	   paints as Newsreader for the Latin run and Noto Serif Telugu for the
	   Telugu run, from this one stack. That is why there is deliberately no
	   "Telugu font" rule anywhere in this project.

	   'Newsreader Fallback' sits directly behind Newsreader — it is Georgia with
	   Newsreader's metrics, declared above, and it holds the shape while the
	   real face loads. It carries no Telugu, so Telugu still falls straight past
	   it to Noto Serif Telugu; plain Georgia stays behind that as the last resort
	   on systems where Georgia is not installed and the local() src fails.

	   v1.10.63 shipped this as Georgia-first, per the prototype. */
	--ts-display: 'Newsreader', 'Newsreader Fallback', 'Noto Serif Telugu', Georgia, 'Times New Roman', serif;
	--ts-body: 'Source Serif 4', 'Noto Serif Telugu', Georgia, serif;
	/* v1.10.77: Inter replaces Poppins as the UI voice. Poppins is not referenced
	   anywhere else in the plugin -- every component resolves through this token --
	   so this single line migrates the whole site, which is the point of having it. */
	--ts-ui: 'Inter', 'Noto Sans Telugu', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

	/* Brand */
	--ts-red: #C8102E;
	--ts-dark-red: #9C0F27;
	--ts-ink: #16181F;
	--ts-muted: #676E7B;
	--ts-hairline: #E8E5DE;
	--ts-gold: #B8892F;
	--ts-wash: #F6F4EF;


	/* Editorial scale. Container-query units (cqi) for block-level roles, because
	   the block architecture is container-based — a vw rule would size a card by
	   the window rather than by the column it sits in. Only the article H1 uses
	   vw: the article template owns the full page width, so there is no container
	   to measure against. Every clamp rises monotonically, so a size can never be
	   larger on mobile than on desktop. */
	--ts-title-hero: clamp(22px, 1.05rem + 1.1cqi, 36px);
	--ts-title-lead: clamp(20px, 1.05rem + 0.7cqi, 28px);
	--ts-title-card: clamp(17px, 1rem + 0.25cqi, 19px);
	--ts-title-compact: clamp(15px, 0.88rem + 0.2cqi, 17px);
	--ts-heading-section: clamp(20px, 1.05rem + 0.6cqi, 26px);
	--ts-title-article: clamp(26px, 1.35rem + 2.1vw, 44px);
	/* v1.10.423 — the DENSE tier, given a name.
	 *
	 * Rail rows, compact cards, video and photo cards and desk supporting
	 * stories are one role: a real story headline in a tight list. They were
	 * never sized as one — the same role was hardcoded at 12.5, 13, 13.5 and 14
	 * across six files, all of them below the point where a serif at 600 stays
	 * comfortable at normal browser zoom. Naming the tier is what lets the six
	 * agree, and lets it be tuned in one place afterwards.
	 *
	 * 14.5px is a deliberate ceiling, not a preference: +1px on the 13.5s, +2px
	 * on the 12.5s. Going further would start eating the information density
	 * these rails exist for.
	 *
	 * Fixed, not a container clamp. The clamped section-heading token produced
	 * five sizes for one role because each rail sits in a different column
	 * width, and that is the mistake this token is named to avoid repeating.
	 */
	/* v1.10.424: 14.5px > 15.5px, after an accessibility review found the tier
	   still uncomfortable on a real desktop page. The cost was measured before
	   the change, by swapping candidates into the live homepage: at 390, 768,
	   1366, 1440 and 1920 the number of clipped headlines is IDENTICAL at 14.5
	   and 15.5, and at 320 it is one higher. Page height grows 28-95px, under
	   0.7%. The tier gets a full millimetre of reading comfort for almost
	   nothing, which is why it moved rather than splitting the difference. */
	--ts-title-dense: 15.5px;
	--ts-lh-dense: 1.4;

	/* The Scope Briefing sits one step above the rest of the dense tier.
	   It is the rail readers spend the most time in and the publication's named
	   product, and — measured — it is the one component that can take 16px with
	   NO cost at all: its rows are sized by the thumbnail, not by the text. */
	--ts-title-brief: 16px;

	/* The standard news card, one step up from dense. Was 16.5px hardcoded. */
	--ts-title-standard: 17.5px;

	--ts-meta: 12px;
	--ts-kicker: 11px;
	--ts-lh-title: 1.22;
	--ts-lh-heading: 1.2;

	/* Back-compat aliases. The article template, site header and careers form
	   already reference these names in 41 places; pointing them at the tokens
	   above makes those usages correct instead of rewriting every one. */
	/* The brief names --ts-font-*; the file has always used --ts-*. Both resolve to
	   the same value so either spelling works and neither can drift. */
	--ts-font-ui: var(--ts-ui);
	--ts-font-display: var(--ts-display);
	--ts-font-body: var(--ts-body);

	--tsp-font-display: var(--ts-display);
	--tsp-font-body: var(--ts-body);
	--tsp-font-ui: var(--ts-ui);

	/* v1.10.56 — adopt Blocksy's own variables instead of fighting its rules.

	   Blocksy styles `body, h1..h6, label, figcaption, …` from
	   `var(--theme-font-family)` and friends, and its stylesheet is enqueued
	   AFTER ours. At equal specificity source order decides, so every attempt to
	   out-declare those rules loses — which is why 69 elements rendered in the
	   OS system font, and why About Us, Careers and Search were system font
	   end to end: the plugin styles nothing on those templates.

	   Blocksy declares these variables at `:root` in
	   uploads/blocksy/css/global.css, which loads BEFORE us, so redefining them
	   here wins cleanly on source order — the same mechanism, used the right way
	   round. The theme keeps rendering its own rules; they now resolve to our
	   brand values. No !important, no theme edit, and anything the theme adds
	   later inherits the brand automatically rather than needing a new override.

	   Only the family, size and leading are remapped. Weight, letter-spacing and
	   text-transform are deliberately left to the theme: they are per-element
	   decisions, and blanket-setting them here would flatten headings site-wide. */
	--theme-font-family: var(--ts-ui);
	--theme-font-size: 16px;
	--theme-line-height: 1.6;

	/* v1.10.57 — the same mechanism applied to heading COLOUR.

	   v1.10.56 remapped the font variables but left the colour ones, so
	   Blocksy's `h3{color:var(--theme-heading-color, …)}` kept painting headings
	   #192A3D. v1.10.56's Task 3 rule only reached `.tsp-story-title`, so
	   section headings and the other rail titles still leaked — measured on
	   Home: ~19 story titles and 5 of 7 section headings.

	   Verified against uploads/blocksy/css/global.css: only
	   `--theme-heading-color` and `--theme-headings-color` are actually
	   DECLARED there. The per-level `--theme-heading-N-color` names appear only
	   as fallbacks inside main.min.css and are never reached while the first is
	   set — they are remapped anyway so the chain cannot resolve to the theme
	   ink if a future Blocksy build stops declaring it.

	   This moves the theme's DEFAULT only. Headings that set `color` on the
	   element — the red accents, the white-on-dark Reviews scorecard — are
	   untouched, because a direct declaration always beats an inherited
	   variable default. */
	--theme-headings-color: var(--ts-ink, #16181F);
	--theme-heading-color: var(--ts-ink, #16181F);
	--theme-heading-1-color: var(--ts-ink, #16181F);
	--theme-heading-2-color: var(--ts-ink, #16181F);
	--theme-heading-3-color: var(--ts-ink, #16181F);
	--theme-heading-4-color: var(--ts-ink, #16181F);
	--theme-heading-5-color: var(--ts-ink, #16181F);
	--theme-heading-6-color: var(--ts-ink, #16181F);
}

/* --------------------------------------------------------------------------
   1. Headlines and titles — one serif, everywhere.

   .tsp-story-title is the shared hook every story title already carries, in
   news-grid cards AND all four sidebar blocks, which is what lets a single
   rule cover both. Weight is bold; size and colour stay with the component.
   -------------------------------------------------------------------------- */
.tsp-story-title,
.tsp-story-title a,
.tsp-news-card h3,
.tsp-feature-card h3,
.tsp-photo-card h3,
.tsp-video-card h3,
.tsp-hero-title,
.tsp-hero h1,
.tsp-hero h2,
.tsp-eb-heading h2,
.tsp-eb-heading h3,
.tsp-eb-heading h4,
.tsp-eb-heading div,
.tsp-sidebar__heading,
.tsp-section-heading,
.tsp-art__title,
.tsp-art__related-h,
.tsp-rail__h3,
.tsp-careers__h {
	font-family: var(--ts-display);
}

/* --------------------------------------------------------------------------
   2. Standfirst / lead summary — the SAME serif as the headline, but regular
   weight and italic so it reads as a lighter voice rather than a second font.
   -------------------------------------------------------------------------- */
.tsp-art__standfirst,
.tsp-hero-excerpt,
.tsp-eb-standfirst,
/* v1.10.152: the opening line of an About/Contact/Careers page is the same
   role as a standfirst — a lighter lead summary under the title — so it joins
   the existing rule rather than introducing a second lede style. */
.tsp-page-lede {
	font-family: var(--ts-display);
	font-weight: 400;
	font-style: italic;
	color: var(--ts-muted);
}

/* --------------------------------------------------------------------------
   3. Long-form reading text.
   -------------------------------------------------------------------------- */
.tsp-art__body,
.tsp-art__body p,
.tsp-art__body ul,
.tsp-art__body ol,
.tsp-art__body blockquote {
	font-family: var(--ts-body);
}
.tsp-art__body p,
.tsp-art__body ul,
.tsp-art__body ol {
	font-size: 19px;
	line-height: 1.75;
}

/* --------------------------------------------------------------------------
   4. Furniture — every label, date, number, control and link that is not a
   headline or reading text. This is the largest group and the one that was
   previously inheriting the theme, which is what made the site look mixed.
   -------------------------------------------------------------------------- */
.tsp-eb-category,
.tsp-sidebar__item-category,
.tsp-sidebar__item-author,
.tsp-sidebar__item-excerpt,
.tsp-eb time,
.tsp-sidebar__item-body time,
.tsp-news-card time,
.tsp-art__crumb,
.tsp-art__kicker,
.tsp-art__bywho,
.tsp-art__bymeta,
.tsp-art__share-lbl,
.tsp-art__tag,
.tsp-art__lead figcaption,
.tsp-art__body figcaption,
.tsp-art__authorbox-t,
.tsp-art__rk,
.tsp-rail__h,
.tsp-rail__adlabel,
.tsp-nav-viewall,
.tsp-nav-btn,
.tsp-nav-live,
.tsp-ad__label,
.tsp-utility-date,
.tsp-eb-heading__note,
.tsp-rating--pending,
.tsp-eb-empty,
.tsp-sidebar-empty,
.tsp-careers__form,
.tsp-careers__intro,
.tsp-pagination,
.tsp-section-intro__filters {
	font-family: var(--ts-ui);
}

/* Rank numerals are furniture, not headlines: they are a counter, so they take
   the UI face at the weight the component sets. */
/* v1.10.36: the numbered rail renders its numeral on ONE of two pseudo-elements
   depending on whether the block shows thumbnails. With images on it is the
   image anchor; with images off that anchor does not exist and the numeral
   hangs off the list item instead. Only the first was listed, so a
   thumbnail-less rail (the Scope Briefing) lost its numeral styling entirely
   and fell back to the theme at 16px. Both are named now. */
.tsp-sidebar__section--numbered .tsp-sidebar__item::before,
.tsp-sidebar__section--numbered .tsp-sidebar__item-image::before,
.tsp-sidebar__section--rank-columns .tsp-sidebar__item::before,
.tsp-rail__n {
	font-family: var(--ts-ui);
}

/* Review scores read as an editorial judgement, so they stay on the display
   serif rather than the UI face. */
.tsp-rating__score,
.tsp-rating__outof {
	font-family: var(--ts-display);
}

/* Form controls do not inherit font-family from their ancestors, so they are
   named explicitly rather than relying on the cascade. */
.tsp-careers input,
.tsp-careers textarea,
.tsp-careers button,
.tsp-hd__search input,
.tsp-art__band input,
.tsp-art__band button,
.tsp-rail--news input,
.tsp-rail--news button {
	font-family: var(--ts-ui);
}

/* ==========================================================================
   5. The editorial SCALE.

   Sizes live here, once, keyed to the shared story-title hook rather than
   repeated per block. Blocks keep their own colour, spacing and clamping; they
   no longer decide how big a headline is.

   Every rule that reads a block attribute keeps that attribute as the OUTER
   value, e.g. var(--tsp-sidebar-title-size, var(--ts-title-compact)). An editor
   who deliberately set a size still wins — the token is only the fallback for
   blocks nobody customised. Those attributes arrive as inline custom properties
   on the block element, so they beat this stylesheet regardless of specificity.
   ========================================================================== */

/* Default story title, used by news-grid cards and all four sidebar blocks. */
.tsp-story-title {
	font-size: var(--ts-title-card);
	line-height: var(--ts-lh-title);
}

/* Lead stories step up one level. */
.tsp-news-card.is-lead .tsp-story-title,
.tsp-news-card.is-lead h3 {
	font-size: var(--tsp-lead-title, var(--ts-title-lead));
}

/* Supporting/compact stories step down one level. */
.tsp-news-card.is-medium .tsp-story-title,
.tsp-news-card.is-compact .tsp-story-title,
.tsp-news-grid--lead-left .tsp-news-card:not(.is-lead) .tsp-story-title,
.tsp-news-grid--lead-right .tsp-news-card:not(.is-lead) .tsp-story-title,
.tsp-news-grid--two-leads-four .tsp-news-card:not(.is-lead) .tsp-story-title,
.tsp-news-grid--sidebar-lead-compact .tsp-news-card:not(.is-lead) .tsp-story-title,
.tsp-news-grid--editorial-row .tsp-news-card .tsp-story-title,
.tsp-news-grid--lead-mosaic .tsp-news-card:not(.is-lead) .tsp-story-title {
	font-size: var(--ts-title-compact);
}

/* Sidebar rails: the editor's own size control stays authoritative. */
.tsp-sidebar__item-body .tsp-story-title {
	font-size: var(--tsp-sidebar-title-size, var(--ts-title-compact));
}

/* Hero. The lead is the largest headline on any page; supports drop to compact
   so a "lead" can never render smaller than the stories beside it. */
.tsp-hero__title {
	font-size: var(--ts-title-hero);
	line-height: var(--ts-lh-title);
}
.tsp-hero__item--support .tsp-hero__title {
	font-size: var(--ts-title-compact);
}

/* Section headings sit above the cards they introduce, so they must be larger
   than them — they were rendering at 12–13px, below every card title. */
.tsp-eb-heading h2,
.tsp-eb-heading h3,
.tsp-eb-heading h4,
.tsp-eb-heading div,
.tsp-section-heading,
.tsp-sidebar__heading {
	font-size: var(--ts-heading-section);
	line-height: var(--ts-lh-heading);
}

/* Article H1 — page-level, so viewport-based. */
.tsp-art__title {
	font-size: var(--ts-title-article);
}

/* Furniture sizing, so kickers and dates stop drifting per block. */
.tsp-eb-category,
.tsp-sidebar__item-category,
.tsp-hero__category,
.tsp-art__kicker,
.tsp-art__rk {
	font-size: var(--ts-kicker);
}
.tsp-eb time,
.tsp-news-card time,
.tsp-sidebar__item-body time,
.tsp-hero__date,
.tsp-art__bymeta {
	font-size: var(--ts-meta);
}

/* Selectors missed by v1.10.33 — these were still inheriting the theme.
   Hero furniture used the wrong class (.tsp-hero-excerpt does not exist; the
   real class is BEM .tsp-hero__excerpt), and the ticker was never listed. */
/* v1.10.422: `.tsp-hero__heading` removed from this list. It was named here AND
   in the display rule directly below, so the file contradicted itself and only
   source order decided the outcome. The display rule is the intended one — the
   hero heading is editorial — and it still wins; this just stops the file from
   arguing with itself. */
.tsp-hero__excerpt,
.tsp-hero__category,
.tsp-hero__date,
.tsp-news-ticker__label,
.tsp-news-ticker__track,
.tsp-news-ticker__track a {
	font-family: var(--ts-ui);
}
.tsp-hero__title,
.tsp-hero__heading {
	font-family: var(--ts-display);
}

/* ==========================================================================
   6. Selectors the browser proved were still outside the system (v1.10.35).

   Found by inspecting computed styles on staging, not by reading source:
   .tsp-section-intro__title was rendering in the THEME's system font at 20px,
   because it had never been listed anywhere. The page title and the photo/video
   title BEM classes were likewise uncovered, and were only looking correct
   because Customizer rules happened to style them.

   These exist so that when the interim Customizer typography is removed, every
   component lands on the token scale rather than falling back to the theme.
   ========================================================================== */
/* v1.10.56: `.tsp-page-title` matched nothing. Blocksy renders its static page
   heading as `<h1 class="page-title">` — verified in the browser on /about-us/,
   which was `-apple-system` at 30px — so the selector had never once applied.
   The old class is kept alongside it rather than swapped out, in case anything
   still emits it. */
.tsp-section-intro__title,
.tsp-page-title,
.page-title {
	font-family: var(--ts-display);
	font-size: var(--ts-heading-section);
	line-height: var(--ts-lh-heading);
}
.tsp-section-intro__description,
.tsp-section-intro__crumb,
.tsp-section-intro__filters,
.tsp-page-title + p {
	font-family: var(--ts-ui);
}
/* Photo and Video titles carry a BEM class as well as being <h3>; naming both
   means the rule survives either markup. */
.tsp-photo-card__title,
.tsp-video-card__title {
	font-family: var(--ts-display);
	font-size: var(--ts-title-card);
	line-height: var(--ts-lh-title);
}
.tsp-photo-card.is-lead .tsp-photo-card__title,
.tsp-video-card.is-featured .tsp-video-card__title {
	font-size: var(--ts-title-lead);
}

/* Rank numerals need a size as well as a face. The Customizer previously
   supplied it; with that removed the numeral had none, so it rendered at the
   theme's 16px body size. Sized as furniture, one step above meta. */
.tsp-sidebar__section--numbered .tsp-sidebar__item::before,
.tsp-sidebar__section--numbered .tsp-sidebar__item-image::before,
.tsp-sidebar__section--rank-columns .tsp-sidebar__item::before,
.tsp-rail__n {
	font-size: var(--ts-title-lead);
	font-weight: 700;
	line-height: 1;
}

/* ==========================================================================
   7. Photo and Video card titles on the shared scale (v1.10.39).

   These carried nine independent sizes (11–22px) across presets. The lead
   tiles were fine — a gallery lead IS a lead-tier element — but the standard
   and compact tiles sat at 13–15px, below the compact floor, so a photo
   headline read smaller than the same headline in a news card.
   ========================================================================== */
.tsp-photo-card__title,
.tsp-video-card h3,
.tsp-video-card__title {
	font-size: var(--ts-title-card);
	line-height: var(--ts-lh-title);
}
.tsp-photo-card.is-lead .tsp-photo-card__title,
.tsp-video-card.is-featured h3,
.tsp-video-card.is-featured .tsp-video-card__title {
	font-size: var(--ts-title-lead);
}
.tsp-photo-gallery--story-strip .tsp-photo-card__title,
.tsp-video-grid--compact-list .tsp-video-card h3 {
	font-size: var(--ts-title-compact);
}

/* ==========================================================================
   8. Theme chrome joins the type system (v1.10.39).

   These are the selectors previously left outside it, so header, footer, nav,
   breadcrumbs, chips and the house ad still rendered in Blocksy's system
   stack while every headline used the brand serif.

   They live here rather than in the child theme because the child theme is not
   activated; the plugin loads on every view, so this is the only place that
   reliably reaches them. If the child theme is ever activated these rules are
   harmless duplicates of its own.

   Deliberately split by ROLE, not by origin: promo and band HEADINGS take the
   display serif, everything functional takes the UI face.
   ========================================================================== */
.ct-menu-link,
.ct-breadcrumbs,
.ct-breadcrumbs a,
.ct-footer,
.ct-footer .widget-title,
.ct-footer ul.wp-block-list,
.ct-footer ul.wp-block-list li a,
.ct-footer .ct-header-text,
.ct-footer .ct-footer-copyright,
.ct-footer .ct-footer-legal,
.ct-footer .ct-footer-lang,
li.lang-telugu > a,
.tsp-chip,
.tsp-chips,
.ts-subscribe > .ct-menu-link,
.ts-section-more,
.ts-section-more a,
.ts-house-ad__label,
.ts-house-ad__sub,
.ts-house-ad__cta,
.aperture-subscribe-btn .wp-block-button__link {
	font-family: var(--ts-ui);
}

/* Headings keep the serif even inside chrome — they are editorial voice. */
.aperture-section-title,
.ts-newsletter-band h2,
.ts-house-ad__title {
	font-family: var(--ts-display);
}

/* ==========================================================================
   9. The last strays (v1.10.40), found by measuring the rendered page.

   Two were VISIBLE: the newsletter band's body copy and the review star
   glyphs. The rest were Blocksy's hidden header and mobile drawer, which the
   Aperture header replaces with display:none — invisible, but styled anyway so
   the site stays correct if that header is ever switched off.
   ========================================================================== */
.ts-newsletter-band p,
.aperture-newsletter p,
.tsp-rating__track,
.tsp-rating__fill {
	font-family: var(--ts-ui);
}

/* Blocksy's own menus. `.ct-menu-link` alone loses to the theme's
   `.mobile-menu a` — same 0-1-1 weight in a sheet that loads later — so these
   are element-qualified to win on specificity rather than with !important. */
a.ct-menu-link,
.mobile-menu a.ct-menu-link,
.ct-panel a.ct-menu-link {
	font-family: var(--ts-ui);
}

/* ==========================================================================
   v1.10.56 — Role consolidation (Tasks 3, 4, 6, 7).

   This block is deliberately LAST in the file. Every rule here is a role
   definition that must beat the per-component rules above it, and at equal
   specificity source order is what decides — the same mechanism the theme was
   winning with, used in our favour. No !important anywhere.
   ========================================================================== */

/* --- Task 4: the section-heading role, reduced to exactly two treatments ----
   Owner decision, 2026-08-08: section headings are POPPINS, not Playfair.
   Serif is what you read; sans is how you navigate.

   v1.10.422 SUPERSEDES that decision, on the owner's instruction: an editorial
   section heading is display type, not navigation. The rule it created is now
   the opposite one — a heading that names a section of the publication or a
   group of stories takes --ts-display; only labels naming a part of a UI
   component or an action stay on --ts-ui.

   That decision was also not reaching the page in the one place it mattered
   most. blocks.css already overrides this rule for `.tsp-eb .tsp-eb-heading
   h2/h3` with the display serif at (0,2,1), so every homepage section heading
   has been rendering Georgia 20/700 regardless of what this said. The families
   now agree instead of one silently beating the other.

   The FIXED 20px is kept deliberately, against the brief's suggestion of
   --ts-heading-section. That token is a container-query clamp, and it is the
   reason this rule exists: it produced FIVE sizes for one role — 25.87 / 24.96
   / 22.15 / 20 / 14 — because each section sits in a different column width.
   Reintroducing it would undo the consistency this pass is for. Weight moves
   600 > 700 to match what blocks.css already renders. */
.tsp-section-heading,
.tsp-eb-heading h2,
.tsp-eb-heading h3,
.tsp-section-intro__title,
.tsp-page-title,
.page-title {
	font-family: var(--ts-display);
	font-size: 20px;
	font-weight: 700;
	letter-spacing: 0.2px;
	text-transform: none;
	line-height: var(--ts-lh-heading);
}

/* Rail / eyebrow heading. Absorbs the Customizer rule
   `.tsp-sidebar .tsp-section-heading--classic{font-size:1.25rem}` (Task 6) —
   that pin existed only because the clamp above was sizing rail headings off
   their container. With a fixed size it is redundant and can be deleted from
   Additional CSS. */
/* v1.10.422: family follows the section-heading role above. These name
   editorial sections — "తెలుగు Highlights", "Most Read" — so they are display
   type at the rail's eyebrow scale, not navigation.

   The uppercase and the 1px tracking are KEPT. Both are deliberate here: the
   rail heading is an eyebrow by design, and at 13px uppercase the tracking is
   what keeps serif capitals legible rather than cramped. Sentence case is not
   forced on them, and the branded wording is untouched. */
.tsp-sidebar__heading,
.tsp-sidebar .tsp-section-heading,
.tsp-sidebar .tsp-section-heading--classic,
.tsp-section-heading--minimal {
	font-family: var(--ts-display);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	line-height: var(--ts-lh-heading);
}

/* --- Task 3: story-title colour, one ink across all four rail blocks -------
   Blocksy's `h3{color:var(--theme-heading-color,…)}` was landing on rail
   titles, so four sibling blocks rendered three different inks (#16181F,
   #192A3D, and the intended #172033). The block's own variable wins here, with
   the token as the fallback rather than the theme's heading colour. */
.tsp-story-title,
.tsp-story-title a,
.tsp-sidebar__item-body .tsp-story-title,
.tsp-sidebar__item-body .tsp-story-title a {
	color: var(--tsp-sidebar-title-color, #172033);
}

/* --- Task 6: view-all / section-more links agree -------------------------
   `.tsp-nav-viewall` was Poppins 14px sentence case while its sibling
   "All sections →" was 12px uppercase with 0.5px tracking. Same control, two
   treatments. This also absorbs the `.ts-section-more a` Additional CSS rule. */
.tsp-nav-viewall,
.tsp-section-intro__all,
.ts-section-more a,
.tsp-eb-heading__note {
	font-family: var(--ts-ui);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.5px;
	text-transform: uppercase;
}

/* --- Task 7: the small leaks --------------------------------------------- */

/* Breadcrumbs: the current-page span is not a link, so it was missing the
   family the sibling anchors got and fell back to the theme's system stack. */
.tsp-section-intro__crumb,
.tsp-section-intro__crumb a,
.tsp-section-intro__crumb span,
.ct-breadcrumbs,
.ct-breadcrumbs a,
.ct-breadcrumbs span {
	font-family: var(--ts-ui);
}

/* Kicker/category had four treatments — 12px untracked, 11px/0.44px,
   11px/0.33px, and 11px untracked with text-transform:none. One role, one
   treatment, on the token. */
.tsp-eb-category,
.tsp-sidebar__item-category,
.tsp-hero__category,
.tsp-photo-card__category,
.tsp-video-card__category,
.tsp-chip {
	font-family: var(--ts-ui);
	font-size: var(--ts-kicker);
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
}

/* Meta: one size (--ts-meta, 12px) and one ink. #667085 was never a token —
   the hero date was also 13px against everything else's 12px. */
.tsp-eb-meta,
.tsp-sidebar__item-meta,
.tsp-news-card time,
.tsp-hero__meta,
.tsp-hero__date,
.tsp-video-card__meta,
.tsp-art__meta {
	font-family: var(--ts-ui);
	font-size: var(--ts-meta);
	color: var(--ts-muted, #676E7B);
}

/* ==========================================================================
   v1.10.57 — residual defects found on staging after v1.10.56.
   ========================================================================== */

/* Defect 2: the 20px main-column section headings were splitting 800/700
   against the locked spec of 600. v1.10.56 already declared 600, but at
   `.tsp-eb-heading h2` — (0,1,1) — which ties with the component rules in
   blocks.css, and that file is enqueued after typography.css, so it won.
   These carry an extra ancestor class to reach (0,2,1) and settle it without
   !important and without editing the component files. */
.tsp-eb .tsp-eb-heading h2,
.tsp-eb .tsp-eb-heading h3,
.tsp-eb-wrap .tsp-eb-heading h2,
.tsp-eb-wrap .tsp-eb-heading h3,
.tsp-section-intro .tsp-section-intro__title,
.tsp-eb .tsp-section-heading,
.tsp-eb-wrap .tsp-section-heading {
	font-weight: 600;
}
/* The eyebrow/rail heading keeps 700 — it is the other of the two locked
   treatments, not a variant of this one. */
.tsp-sidebar .tsp-sidebar__heading,
.tsp-sidebar .tsp-section-heading,
.tsp-sidebar .tsp-section-heading--classic,
.tsp-section-heading--minimal {
	font-weight: 700;
}

/* Defect 1, belt to the :root braces: section headings and rail titles take the
   brand ink explicitly, so they no longer depend on which variable Blocksy
   happens to resolve. Anything that sets its own colour still wins — this is a
   default, declared once, not an override chain. */
.tsp-section-heading,
.tsp-section-intro__title,
.tsp-eb-heading h2,
.tsp-eb-heading h3,
.tsp-sidebar__heading {
	color: var(--tsp-heading-color, var(--ts-ink, #16181F));
}

/* ==========================================================================
   v1.10.58 Part A — heading and story-title ink.

   THE CAUSE IS NOT BLOCKSY. Traced in the rendered page rather than assumed:
   Customizer Additional CSS is redefining one of the PLUGIN's own tokens —

     :root{--ts-title-ink:#192a3d;--tsp-title-color:var(--ts-title-ink);}

   Every plugin rule that resolves colour through `--tsp-title-color` therefore
   paints #192A3D, no matter what the theme variables say. That is exactly why
   v1.10.57's `:root` remap measured as applied and yet changed nothing here,
   and why the SAME class is right inside `.entry-content` (a rule there sets
   ink directly) and wrong inside a column or the sidebar (those go through the
   token). Blocksy's own `h1..h6{color:var(--theme-heading-color,…)}` rules are
   only (0,0,1) — the plugin's class rules already outrank them.

   So the fix is not more specificity against the theme. These roles resolve to
   `--ts-ink` DIRECTLY, a token Additional CSS does not touch, instead of going
   through the hijacked one. That also means the fix holds once Additional CSS
   is emptied — it does not depend on it either way.

   Intentional exceptions are untouched: white-on-dark (Reviews scorecard) and
   red accents set `color` on the element, which beats an inherited default. */
.tsp-section-intro__title,
.tsp-section-heading,
.tsp-eb-heading h2,
.tsp-eb-heading h3,
.tsp-story-title,
.tsp-story-title a,
.tsp-sidebar__heading,
.tsp-sidebar__item-body .tsp-story-title,
.tsp-sidebar__item-body .tsp-story-title a {
	color: var(--ts-ink, #16181F);
}

/* ==========================================================================
   v1.10.59 Part A — one container token, shared with the header.

   Owner decision: the header stays at 1200 and the body narrows to match.

   Blocksy puts body content on a 1500px/90vw container, so content sat at
   L64 while the nav sat at L145. The rule doing it is WordPress core's, printed
   inline in <head>:

     .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull))
       { max-width: var(--wp--style--global--content-size) }

   `:where()` contributes nothing, so that is (0,1,0) — the same as a single
   class — and being inline in <head> it wins every tie. Enqueue order cannot
   beat an inline <head> rule, so the plugin's selectors are scoped one level up
   to (0,2,0) instead. No !important, and nothing touches a core block globally.
   ========================================================================== */
:root{
	/* v1.10.318: follow the tiered editorial shell. This was a hard 1200px, which
	   is what pinned every homepage section while the header, category, corporate
	   and review shells moved to --tsp-shell. Measured before the change: at 1920
	   the homepage hero started at 380 while HOME sat at 230 and POLITICS at 301 --
	   the homepage literally began past the second nav item; at 2560 it was 700
	   against HOME at 420. Category pages were already correct because .tsp-cat-wrap
	   reads --tsp-shell directly.
	   --tsp-shell is 1200 below 1536, so 1366 and 1440 are unchanged, and
	   .tsp-art-wrap still overrides --tsp-wrap locally to keep the article at 1500. */
	--tsp-wrap: var(--tsp-shell, 1200px);
	--tsp-gutter: 20px;
	/* The ticker rule already referenced this name but nothing ever defined it,
	   so it fell back and was then overridden to 1500px anyway. */
	--tsp-eb-wrap: var(--tsp-wrap);
}

.entry-content .tsp-container,
.entry-content .tsp-eb,
.entry-content .tsp-eb-wrap,
.entry-content .tsp-ad,
.entry-content .tsp-news-ticker,
.entry-content .tsp-hero-wrap,
.entry-content .tsp-sidebar-wrap,

.entry-content .ts-section-more,
.entry-content .tsp-page-title,
.entry-content .page-title{
	width: 100%;
	max-width: var(--tsp-wrap);
	margin-inline: auto;
	padding-inline: var(--tsp-gutter);
	box-sizing: border-box;
}

/* Core markup (the three .wp-block-columns and the newsletter band) is scoped to
   the plugin's own page context rather than styled globally, so no other site
   using these blocks is affected. */
.entry-content > .wp-block-columns,
.entry-content > .wp-block-group{
	width: 100%;
	max-width: var(--tsp-wrap);
	margin-inline: auto;
	padding-inline: var(--tsp-gutter);
	box-sizing: border-box;
}

/* Nested wrappers must not gutter twice — only the outermost band pads. */
.entry-content .tsp-eb-wrap .tsp-eb,
.entry-content .wp-block-columns .tsp-eb,
.entry-content .wp-block-columns .tsp-eb-wrap,
.entry-content .wp-block-columns .tsp-ad{
	max-width: none;
	padding-inline: 0;
}

/* v1.10.60 Correction 1 — the newsletter band is FULL-BLEED.

   v1.10.59 put `.ts-newsletter-band` in the 1200px container utility, which
   capped the RED BACKGROUND itself — so on a wide screen it rendered as a boxed
   red rectangle with white gutters either side. The band is a full-bleed
   element: the colour runs edge to edge and only the content inside it is
   constrained.

   Done by targeting the band's children rather than adding a wrapper, so no
   markup changes and the pattern keeps working wherever it is placed.

   The dark Reviews band is deliberately NOT included: in the design that one is
   a contained card at 1200px, so it stays capped. */
.entry-content > .ts-newsletter-band,
.entry-content .ts-newsletter-band{
	max-width: none;
	padding-inline: 0;
}
.entry-content .ts-newsletter-band > *{
	max-width: var(--tsp-wrap);
	margin-inline: auto;
	padding-inline: var(--tsp-gutter);
	box-sizing: border-box;
}


/* Aperture align fix — hero/sidebar sit inside padded columns; drop the double gutter so hero aligns to the content edge and briefing to the container edge. */
.entry-content .tsp-hero-wrap, .entry-content .tsp-sidebar-wrap { padding-inline: 0; }

/* ============================================================================
   EDITORIAL SHELL WIDTH — site-wide tiered container system (v1.10.313)
   ============================================================================

   The problem this solves, measured on staging before the change:

                   1366   1440   1600   1920   2560
     footer inner  1229   1296   1440   1500   1500   <- Blocksy, scales then caps
     .tsp-cat-wrap 1200   1200   1200   1200   1200   <- plugin, FIXED
     .tsp-art__inner 1200 1200   1200   1200   1200   <- plugin, FIXED

   At 1366 the two systems are 29px apart and read as one grid — that is the
   approved laptop composition. At 1920 they are 300px apart: the footer runs to
   1500 while the editorial column stays at 1200. The site looks narrow on a
   24-inch monitor because of that ASYMMETRY, not because 1200 is small.

   So this is not "make 1200 bigger". It is one token, stepped, that the plugin
   shells and Blocksy's own container both follow, so they stop disagreeing.

   PROTECTED BASELINE: no tier below 1536px. 1366 and 1440 resolve to 1200px,
   byte-identical to the approved layout. Growth begins only above the laptop
   range.

   Article prose is deliberately NOT on this token — --tsp-read stays 720px at
   every width. Extra width goes to the rail and the composition, never to
   longer text lines. */

:root{
	--tsp-shell:1200px;
	--tsp-rail:320px;
}

/* v1.10.335  the footer joins the site grid.

   Blocksy sizes its container as min(90%, --theme-normal-container-max-width).
   We only fed that variable from 1536 up, so below it the footer used 90% of the
   viewport while the editorial shell was capped at 1200  and above it the
   footer sat on the shell EDGE while the content sat one gutter inside. Neither
   line agreed with the page above. Measured, footer content vs content line:

     1280  +4px      1366  -35px     1440  -68px     >=1536  -20px

   Feeding the variable the shell MINUS its two gutters lands the footer's
   content on exactly the same line as the cards above it, at every tier, with
   no per-width rule: (viewport - (shell - 2*gutter)) / 2 == shell_left + gutter.

   Scoped to .ct-footer so the theme's other containers keep their own sizing,
   and expressed in the existing tokens so new tiers inherit it automatically.
   The 90% clamp still wins on phones, so the mobile accordion is untouched. */
.ct-footer{--theme-normal-container-max-width:calc(var(--tsp-shell,1200px) - 2 * var(--tsp-gutter,20px))}

/* Laptop range ends here. Everything below 1536 is untouched. */

@media (min-width:1536px){
	:root{--tsp-shell:1320px;--tsp-rail:340px;--theme-normal-container-max-width:1320px}
}
@media (min-width:1728px){
	:root{--tsp-shell:1420px;--tsp-rail:350px;--theme-normal-container-max-width:1420px}
}
/* 1500 is Blocksy's own cap. Meeting it exactly is what removes the asymmetry
   that made 1920 feel narrow. */
@media (min-width:1920px){
	:root{--tsp-shell:1500px;--tsp-rail:360px;--theme-normal-container-max-width:1500px}
}
@media (min-width:2560px){
	:root{--tsp-shell:1760px;--tsp-rail:380px;--theme-normal-container-max-width:1760px}
}
/* Final cap. Beyond this the page centres with large outer margins rather than
   growing — a publication, not a website stretched across a television. */
@media (min-width:3440px){
	:root{--tsp-shell:1920px;--tsp-rail:400px;--theme-normal-container-max-width:1920px}
}

/* v1.10.517 — the footer's edition switcher becomes a real tap target.

   Measured at 390 on the deployed footer: the two links are 39x14 and 32x14.
   WCAG 2.2 AA (2.5.8 Target Size, Minimum) asks for 24x24 CSS pixels, and a
   14px-tall target is the hardest thing on the page to hit on a phone — which
   matters more here than almost anywhere else, because these two links are how
   a reader moves between the English and Telugu editions.

   Padding rather than font-size: the type stays 11.5px, so the footer's visual
   rhythm is untouched and only the hit area grows. `inline-block` is what lets
   the vertical padding count at all — the links are `display: inline`, where
   block-direction padding does not affect the box's own height.

   14 + 2x6 = 26px tall, 39 + 2x6 = 51px wide. The negative inline margin keeps
   the text's optical start where it already sits, so nothing visibly moves. */
.ct-footer .ct-footer-lang a {
	display: inline-block;
	padding: 6px;
	margin-inline: -6px;
}

/* ==========================================================================
   v1.10.669 — PORTRAIT SAFETY NET, site-wide.

   A photograph taller than it is wide cannot be cropped into a landscape card
   without discarding most of it, so `Video_Poster::thumbnail_html()` marks it
   and hands over the uncropped derivative. This is the one rule that makes that
   marker mean something on every surface at once.

   It lives in typography.css because that sheet is enqueued unconditionally on
   every front-end route, and this must not depend on which component-scoped
   stylesheet a given page happened to load — the defect it prevents is a
   subject with their head cut off.

   `background-color` on the <img> itself is what fills the letterbox. An image
   paints its own background behind its content, so this needs no wrapper
   element — which matters, because the twelve call sites build their own markup
   and inserting a wrapper into each would break the flex, grid and
   aspect-ratio rules written against them.

   The two surfaces that DO have a wrapper — the Scope Briefing tile and the
   tsp-cat rows and cards — add a blurred, darkened copy behind this. So the
   treatment degrades to charcoal-only where there is nowhere to put a backdrop,
   and never to a stretched or cropped photograph.

   GEOMETRY IS UNTOUCHED: only object-fit and a background colour change, so no
   card box, row height or column track can move.
   ========================================================================== */

/*
 * THE CLASS IS REPEATED ON PURPOSE, and this is the whole reason the first
 * attempt failed. `img.tsp-img--portrait` is (0,1,1), which merely TIES the
 * component rules that set `object-fit: cover` — `.tsp-cat__row-media img`,
 * `.tsp-sidebar__item-image img` and their siblings — so the winner is decided
 * by which stylesheet loaded last, and typography.css loads first. Measured on
 * the deployed v1.10.669: the marker was on the image and the charcoal WAS
 * applied, because nothing else sets a background there, while `object-fit`
 * stayed `cover` on every one of them.
 *
 * Repeating the class raises this to (0,3,1) and settles it by specificity
 * rather than by load order, which is not something this rule can know. That is
 * the sanctioned idiom here: CODING-STANDARDS forbids `!important` outside the
 * editor sheet, and this is exactly the case it is forbidden for.
 */
img.tsp-img--portrait.tsp-img--portrait.tsp-img--portrait {
	object-fit: contain;
	object-position: center center;
	background-color: var(--ts-ink, #16181F);
}
