/*
Theme Name: Discovery Lite
Theme URI: https://github.com/discovery-team/discovery-lite
Author: Discovery Team
Author URI: https://github.com/discovery-team
Description: Ultra-light, mobile-first blog/news theme engineered for Google Discover. Infinite article feed, AI summary cards, read-more collapse, emoji reactions, voted comments, trending carousel, Beeps short-news cards, ad slots, emoji reactions and a built-in translation layer. No jQuery, no webfonts, no build step.
Version: 1.95.0
Requires at least: 6.4
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: discovery-lite
Tags: blog, news, one-column, custom-menu, custom-logo, custom-colors, featured-images, threaded-comments, translation-ready, block-styles, wide-blocks
*/

/* ==========================================================================
   1. Tokens
   ========================================================================== */
:root{
	--dsc-accent:#6d28d9;
	--dsc-accent-ink:#fff;
	--dsc-ink:#111418;
	--dsc-ink-2:#474c52;
	--dsc-ink-3:#6b7177;
	--dsc-line:#e4e7ea;
	--dsc-bg:#fff;
	--dsc-bg-2:#f6f7f9;
	--dsc-bg-3:#eef1f5;
	--dsc-radius:14px;
	--dsc-radius-sm:9px;
	--dsc-wrap:720px;
	--dsc-wrap-wide:1140px;
	--dsc-gap:16px;
	--dsc-font-body:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
	--dsc-font-head:Georgia,"Iowan Old Style","Times New Roman",serif;
	--dsc-title-scale:1;
	--dsc-body-size:1.075rem;
	--dsc-lh:1.62;
	--dsc-shadow:0 1px 2px rgba(16,24,40,.06),0 8px 24px -12px rgba(16,24,40,.18);
	--dsc-header-h:56px;
}
/* Day/night switch. Both sides stay lit so the control reads as a switch; the
   knob slides to the side that is on. */
.dsc-scheme{position:relative;display:inline-flex;align-items:center;flex:none;padding:3px;border:1px solid var(--dsc-line);border-radius:999px;background:var(--dsc-bg-2);cursor:pointer;line-height:0}
.dsc-scheme__knob{position:absolute;top:3px;left:3px;width:26px;height:26px;border-radius:50%;background:var(--dsc-bg);box-shadow:0 1px 3px rgba(0,0,0,.18);transition:transform .18s ease}
.dsc-scheme[aria-pressed=true] .dsc-scheme__knob{transform:translateX(26px)}
.dsc-scheme__side{position:relative;display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;color:var(--dsc-ink-3);transition:color .18s ease}
.dsc-scheme[aria-pressed=false] .dsc-scheme__side:first-of-type,
.dsc-scheme[aria-pressed=true] .dsc-scheme__side:last-of-type{color:var(--dsc-ink)}
@media (prefers-reduced-motion:reduce){.dsc-scheme__knob{transition:none}}
[data-dsc-fonts="sans"]{--dsc-font-head:system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif}
[data-dsc-fonts="serif"]{--dsc-font-body:Georgia,"Iowan Old Style","Times New Roman",serif}

@media (prefers-color-scheme:dark){
	:root[data-dsc-scheme="auto"]{
		color-scheme:dark;
		--dsc-ink:#e8eaed;--dsc-ink-2:#b6bbc1;--dsc-ink-3:#9aa0a6;
		--dsc-line:#2b2f34;--dsc-bg:#121417;--dsc-bg-2:#191c20;--dsc-bg-3:#22262b;
		--dsc-shadow:0 1px 2px rgba(0,0,0,.5),0 8px 24px -12px rgba(0,0,0,.7);
	}
}
:root[data-dsc-scheme="dark"]{
	color-scheme:dark;
	--dsc-ink:#e8eaed;--dsc-ink-2:#b6bbc1;--dsc-ink-3:#9aa0a6;
	--dsc-line:#2b2f34;--dsc-bg:#121417;--dsc-bg-2:#191c20;--dsc-bg-3:#22262b;
}

/* ==========================================================================
   2. Reset / base
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box}
/* A class that sets `display` outranks the browser's own [hidden] rule, so any
   element toggled by the `hidden` attribute would stay visible. Enforce it once
   here instead of remembering it at every call site. */
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{animation-duration:.01ms!important;transition-duration:.01ms!important}}

/* The scrollbar, in the site's own colours.
   pointer:fine rather than a width breakpoint — this is about the input device,
   not the screen. Phones and tablets draw an overlay bar that appears while the
   finger moves and disappears after it, sized and coloured by the system; a
   laptop with a touchscreen still has a mouse and still wants the styled one.
   Two ways of saying it, because no browser takes both. Firefox and Chrome from
   121 read scrollbar-color and ignore the ::-webkit rules; Safari and older
   Chrome do the opposite. The webkit version can do what the standard one
   cannot: a thumb inset from its own track, drawn as a border in the page
   colour, which is what makes the bar read as a slim pill rather than a gutter.
   Colours come from the theme variables, so the accent and the dark scheme are
   already handled — nothing here is a literal colour. */
@media (pointer:fine){
	html{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--dsc-accent) 45%,var(--dsc-line)) transparent}

	::-webkit-scrollbar{width:12px;height:12px}
	::-webkit-scrollbar-track{background:transparent}
	::-webkit-scrollbar-thumb{
		background:color-mix(in srgb,var(--dsc-accent) 45%,var(--dsc-line));
		border-radius:999px;
		/* Transparent would show the track through it; the page colour is what
		   gives the thumb its margin without a second element to draw it. */
		border:3px solid var(--dsc-bg);
	}
	::-webkit-scrollbar-thumb:hover{background:var(--dsc-accent)}
	/* Where the two bars meet. Left alone it is a pale grey square that belongs
	   to no scheme in particular and is very visible in the dark one. */
	::-webkit-scrollbar-corner{background:transparent}
}
body{
	margin:0;background:var(--dsc-bg);color:var(--dsc-ink);
	font-family:var(--dsc-font-body);font-size:var(--dsc-body-size);line-height:var(--dsc-lh);
	-webkit-font-smoothing:antialiased;overflow-wrap:break-word;
	/* Sticky footer: a thin page (a tag archive with one post) would otherwise
	   leave the footer floating in the middle of the screen. */
	display:flex;flex-direction:column;min-height:100vh;
}
#dsc-main{flex:1 0 auto}
.dsc-footer{margin-top:auto}
img,video,iframe,svg{max-width:100%;height:auto}
img{display:block}
a{color:var(--dsc-accent);text-decoration-thickness:1px;text-underline-offset:2px}
a:hover{text-decoration-thickness:2px}
:focus-visible{outline:3px solid var(--dsc-accent);outline-offset:2px;border-radius:4px}
button{font:inherit;color:inherit}
/* text-wrap:balance evens out the last line, which reads well on a wide screen
   and badly on a phone: with 3–4 words per line it produces short ragged rows.
   Phones get `pretty` (only avoids orphans), desktops get `balance`. */
h1,h2,h3,h4{font-family:var(--dsc-font-head);line-height:1.16;letter-spacing:-.015em;margin:1.6em 0 .5em;text-wrap:pretty;overflow-wrap:break-word}
@media (min-width:700px){h1,h2,h3,h4{text-wrap:balance}}
p,ul,ol,blockquote,figure,table{margin:0 0 1.15em}
figure{margin-inline:0}
hr{border:0;border-top:1px solid var(--dsc-line);margin:2em 0}
blockquote{border-left:2px solid var(--dsc-line);padding:.2em 0 .2em 1.1em;margin-left:0;color:var(--dsc-ink-2);font-style:italic}
code,pre{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em}
pre{background:var(--dsc-bg-2);padding:1em;border-radius:var(--dsc-radius-sm);overflow:auto}
table{border-collapse:collapse;width:100%}
th,td{border:1px solid var(--dsc-line);padding:.5em .7em;text-align:start}

.dsc-wrap{width:100%;max-width:var(--dsc-wrap);margin-inline:auto;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right))}
.dsc-wrap--wide{max-width:var(--dsc-wrap-wide)}
.screen-reader-text{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.dsc-skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--dsc-bg);color:var(--dsc-ink);padding:12px 18px;border-radius:0 0 var(--dsc-radius-sm) 0}
.dsc-skip:focus{left:0}

/* ==========================================================================
   3. Header / nav
   ========================================================================== */
.dsc-header{position:sticky;top:0;z-index:40;background:var(--dsc-bg);border-bottom:1px solid var(--dsc-line)}
.dsc-header__bar{display:flex;align-items:center;gap:12px;min-height:var(--dsc-header-h);max-width:var(--dsc-wrap-wide);margin-inline:auto;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right))}

/* centred masthead: logo + tagline above the menu bar */
.dsc-masthead{text-align:center;padding:22px 16px 14px}
.dsc-masthead__logo img{margin-inline:auto;max-height:calc(var(--dsc-logo-h,44px) * 1.9);width:auto;object-fit:contain}
.dsc-masthead__name{display:inline-block;font-family:var(--dsc-font-head);font-weight:800;font-size:1.7rem;letter-spacing:-.02em;color:var(--dsc-ink);text-decoration:none}
.dsc-masthead__tagline{margin:8px 0 0;font-size:.92rem;color:var(--dsc-ink-3)}
.dsc-head-centered .dsc-header{position:static}
.dsc-head-centered .dsc-header__bar{background:var(--dsc-nav-bg,transparent);color:var(--dsc-nav-ink,inherit);max-width:none;position:sticky;top:0;z-index:40}
.dsc-head-centered .dsc-header__bar .dsc-iconbtn{color:var(--dsc-nav-ink,var(--dsc-ink))}
/* Centring only makes sense once the menu is on screen; on mobile the bar is
   burger-left / icons-right like the compact layout. */
@media (min-width:900px){
	.dsc-head-centered .dsc-header__bar{justify-content:center}
	.dsc-head-centered .dsc-header__spacer{flex:0}
	/* The nav fills the bar, so centring has to happen inside the list. */
	.dsc-head-centered .dsc-nav__menu{justify-content:center}
	/* The logo already sits in the masthead above — the second row does not grow
	   with it. */
	.dsc-head-centered .dsc-header__bar{min-height:56px}
	/* Still scrollable in the extreme case, with a visible scrollbar. */
	.dsc-nav{scrollbar-width:thin}
	.dsc-nav::-webkit-scrollbar{display:block;height:6px}
	.dsc-nav::-webkit-scrollbar-thumb{background:var(--dsc-line);border-radius:3px}
}
/* In the centred layout the masthead scrolls away on a phone; without this the
   sticky bar is a burger and two icons with nothing identifying the site. */
/* Full-width top bar: the wrapper limit is dropped, the safe-area padding stays. */
.dsc-head-full .dsc-header__bar,.dsc-head-full .dsc-rail__inner{max-width:none}

.dsc-brand--mini{font-size:1.05rem;font-weight:800;font-family:var(--dsc-font-head);color:var(--dsc-nav-ink,var(--dsc-ink));text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The sticky bar is shorter than the masthead, so the logo rides smaller here. */
.dsc-brand--mini img,.dsc-brand--mini .custom-logo{max-height:min(var(--dsc-logo-h,44px),34px)}
@media (min-width:900px){.dsc-brand--mini{display:none}}

/* desktop horizontal menu — the burger is mobile-only */
.dsc-nav{display:none;flex:1 1 auto;min-width:0;overflow-x:auto;scrollbar-width:none}
.dsc-nav::-webkit-scrollbar{display:none}
/* The logo must not be the thing that gives way when the bar runs out of room.
   With `overflow:hidden` a flex item's automatic minimum size becomes zero, so
   on a narrow phone the brand was shrinking to nothing and the logo simply
   vanished. Only the text version may be clipped; an image keeps its width and
   is capped instead. */
.dsc-has-nav .dsc-brand{flex:0 0 auto;min-width:0}
.dsc-has-nav a.dsc-brand{overflow:hidden;text-overflow:ellipsis}
.dsc-brand img,.dsc-brand .custom-logo{max-width:min(46vw,240px)}
.dsc-nav__menu{display:flex;align-items:center;gap:2px;list-style:none;margin:0;padding:0}
.dsc-nav__menu li{position:relative}
/* --dsc-nav-size is set by JS when the menu has to shrink to stay on one bar. */
.dsc-nav__menu a{display:block;padding:10px clamp(7px,0.7vw,12px);font-size:var(--dsc-nav-size,.9rem);font-weight:700;text-transform:uppercase;letter-spacing:.01em;color:var(--dsc-nav-ink,var(--dsc-ink));text-decoration:none;white-space:nowrap;border-radius:8px}
.dsc-nav__menu a:hover{background:rgba(127,127,127,.14)}
.dsc-nav__menu .current-menu-item>a{text-decoration:underline;text-underline-offset:5px}
.dsc-nav__menu .sub-menu{display:none;position:absolute;left:0;top:100%;min-width:220px;background:var(--dsc-bg);border:1px solid var(--dsc-line);border-radius:var(--dsc-radius-sm);box-shadow:var(--dsc-shadow);padding:6px;list-style:none;margin:0;z-index:50}
.dsc-nav__menu li:hover>.sub-menu,.dsc-nav__menu li:focus-within>.sub-menu{display:block}
.dsc-nav__menu .sub-menu a{color:var(--dsc-ink);text-transform:none;font-weight:600}
/* A menu too wide to sit beside the logo drops onto its own full-width row —
   the class is set in JS after measuring. Declared after .dsc-has-nav and with
   the bar's own class in the selector, so the spacer really does push the bell
   and the search icon to the right edge. */
@media (min-width:900px){
	.dsc-header__bar.dsc-bar--stack{flex-wrap:wrap;padding-bottom:0;row-gap:0}
	.dsc-header__bar.dsc-bar--stack .dsc-header__spacer{flex:1 1 auto}
	.dsc-header__bar.dsc-bar--stack .dsc-nav{flex:1 0 100%;order:9;width:100%;min-width:0;max-width:100%;border-top:1px solid var(--dsc-line);overflow:visible}
	/* Wrapping beats scrolling: a centred overflow strip cuts BOTH ends and
	   nothing tells the reader the rest exists. */
	.dsc-header__bar.dsc-bar--stack .dsc-nav__menu{flex-wrap:wrap;justify-content:center;padding:3px 0;row-gap:0}
	.dsc-header__bar.dsc-bar--stack .dsc-nav__menu a{padding:9px 10px;font-size:.85rem;letter-spacing:0;white-space:normal;text-align:center}
}

@media (min-width:900px){
	/* Selector is deliberately specific: .dsc-iconbtn sets display later in the
	   file, and an equally specific rule here would lose to it. */
	.dsc-header__bar .dsc-burger{display:none}
	.dsc-nav{display:block}
	/* Only once the menu is actually visible does it take the free space; on
	   mobile the spacer must keep pushing the icons to the right edge. */
	.dsc-has-nav .dsc-header__spacer{flex:0 0 8px}
	.dsc-head-centered .dsc-header__bar{height:52px}
	/* The auto category rail repeats the primary menu on desktop — drop it.
	   A hand-assigned "Category rail" menu is different content, so it stays. */
	.dsc-auto-rail.dsc-has-nav .dsc-rail{display:none}
}
.dsc-brand{display:flex;align-items:center;gap:8px;font-family:var(--dsc-font-head);font-weight:700;font-size:1.22rem;letter-spacing:-.02em;color:var(--dsc-ink);text-decoration:none;white-space:nowrap}
.dsc-brand img,.dsc-brand .custom-logo{max-height:var(--dsc-logo-h,44px);width:auto;object-fit:contain}
.dsc-header__spacer{flex:1}
.dsc-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border:0;background:none;border-radius:50%;cursor:pointer;color:var(--dsc-ink);flex:none}
.dsc-iconbtn:hover{background:var(--dsc-bg-2)}
.dsc-iconbtn svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* "Prefer this source in Google" — a bare bell reads as a notifications bell,
   so it carries a word on anything wider than a phone. */
.dsc-follow{display:inline-flex;align-items:center;gap:6px;flex:none;height:36px;padding:0 12px;border:1px solid var(--dsc-line);border-radius:999px;color:var(--dsc-ink);text-decoration:none;font-size:.85rem;font-weight:700;white-space:nowrap}
.dsc-follow:hover{border-color:currentColor}
.dsc-follow svg{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex:none}
.dsc-follow__label{display:none}
@media (min-width:600px){.dsc-follow__label{display:inline}}
.dsc-head-centered .dsc-follow{color:var(--dsc-nav-ink,var(--dsc-ink));border-color:currentColor}

/* category rail — horizontal scroll like Discover / TOI */
.dsc-rail{border-bottom:1px solid var(--dsc-line);background:var(--dsc-bg)}
.dsc-rail__inner{display:flex;gap:4px;overflow-x:auto;scrollbar-width:none;max-width:var(--dsc-wrap-wide);margin-inline:auto;padding:0 12px;scroll-snap-type:x proximity;overscroll-behavior-x:contain}
.dsc-rail__inner::-webkit-scrollbar{display:none}
.dsc-rail a{flex:none;scroll-snap-align:start;padding:11px 12px;font-size:.95rem;font-weight:600;color:var(--dsc-ink-2);text-decoration:none;border-bottom:3px solid transparent;white-space:nowrap}
.dsc-rail a:hover{color:var(--dsc-ink)}
.dsc-rail a[aria-current],.dsc-rail .current-menu-item>a,.dsc-rail .current-menu-parent>a{color:var(--dsc-accent);border-bottom-color:var(--dsc-accent)}
.dsc-rail__inner ul,.dsc-rail__inner li{display:contents;list-style:none;margin:0;padding:0}

/* slide-in menu */
.dsc-drawer{position:fixed;inset:0 auto 0 0;width:min(86vw,340px);background:var(--dsc-bg);z-index:60;transform:translateX(-102%);transition:transform .22s ease;padding:14px;padding-left:max(14px,env(safe-area-inset-left));padding-bottom:max(14px,env(safe-area-inset-bottom));overflow-y:auto;overscroll-behavior:contain;border-right:1px solid var(--dsc-line)}
.dsc-drawer[data-open]{transform:none}
.dsc-drawer ul{list-style:none;margin:0;padding:0}
.dsc-drawer li a{display:block;padding:12px 10px;border-radius:var(--dsc-radius-sm);color:var(--dsc-ink);text-decoration:none;font-weight:600}
.dsc-drawer li a:hover{background:var(--dsc-bg-2)}
.dsc-drawer .sub-menu a{padding-left:24px;font-weight:400;color:var(--dsc-ink-2)}
.dsc-scrim{position:fixed;inset:0;background:rgba(6,10,16,.45);z-index:55;opacity:0;pointer-events:none;transition:opacity .2s}
.dsc-scrim[data-open]{opacity:1;pointer-events:auto}

/* search sheet */
.dsc-searchsheet{display:none;border-bottom:1px solid var(--dsc-line);background:var(--dsc-bg-2);padding:10px 0}
.dsc-searchsheet[data-open]{display:block}
/* Same track as the header bar: the field starts under the logo and ends under
   the search icon, whatever the article width is set to. */
.dsc-searchform{display:flex;gap:8px;max-width:var(--dsc-wrap-wide);margin-inline:auto;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right))}
.dsc-searchform input[type=search]{flex:1;min-width:0;border:1px solid var(--dsc-line);background:var(--dsc-bg);color:var(--dsc-ink);border-radius:999px;padding:11px 16px;font-size:1rem}
.dsc-searchform button{border:0;background:var(--dsc-accent);color:var(--dsc-accent-ink);border-radius:999px;padding:0 18px;font-weight:600;cursor:pointer}

/* The WP admin bar is fixed at the top for logged-in users, so everything
   sticky has to start below it.
   The headings belong in this list too. Moving the sticky stack down without
   moving the place a jump-link lands means the heading lands under the stack:
   the section tabs sat at 142px while the heading was still being put at 121px,
   so clicking an entry in the contents put its own heading 18px behind the bar
   it was clicked from. Readers never saw it — only whoever was logged in, which
   is why it survived. Every offset here is the same number in four places; a
   change to one is a change to all four. */
.admin-bar .dsc-header,
.admin-bar .dsc-head-centered .dsc-header__bar{top:32px}
.admin-bar .dsc-tocbar{top:calc(var(--dsc-header-real,var(--dsc-header-h)) + 32px)}
.admin-bar .dsc-progress{top:32px}
.admin-bar .dsc-body>h2,
.admin-bar .dsc-body>h3{scroll-margin-top:calc(var(--dsc-header-real,var(--dsc-header-h)) + 92px)}
/* 601px, not 0: WordPress lets the admin bar scroll away with the page below
   600px — it stops being fixed and stops being in the way. Offsetting for it
   anyway left a 46px band at the top of the screen on a phone with the article
   scrolling through it and the purple progress line hanging under it, which is
   what an editor checking their own post on a phone sees and a reader never
   does. The header sits over the bar at the very top of the page instead; the
   bar is a strip an editor scrolls past, the gap was on screen the whole time.
   The measured version of this rule is in app.js — only a bar that computes to
   position:fixed counts. */
@media screen and (min-width:601px) and (max-width:782px){
	.admin-bar .dsc-header,
	.admin-bar .dsc-head-centered .dsc-header__bar{top:46px}
	.admin-bar .dsc-tocbar{top:calc(var(--dsc-header-real,var(--dsc-header-h)) + 46px)}
	.admin-bar .dsc-progress{top:46px}
	.admin-bar .dsc-body>h2,
	.admin-bar .dsc-body>h3{scroll-margin-top:calc(var(--dsc-header-real,var(--dsc-header-h)) + 106px)}
}
@media screen and (max-width:600px){
	.admin-bar .dsc-header,
	.admin-bar .dsc-head-centered .dsc-header__bar{top:0}
	.admin-bar .dsc-tocbar{top:var(--dsc-header-real,var(--dsc-header-h))}
	.admin-bar .dsc-progress{top:0}
	.admin-bar .dsc-body>h2,
	.admin-bar .dsc-body>h3{scroll-margin-top:calc(var(--dsc-header-real,var(--dsc-header-h)) + 60px)}
}

/* reading progress */
.dsc-progress{position:fixed;top:0;left:0;height:3px;width:100%;transform:scaleX(0);transform-origin:0 50%;background:var(--dsc-accent);z-index:50;will-change:transform}

/* ==========================================================================
   4. Cards / grids
   ========================================================================== */
.dsc-section{margin:28px 0}
.dsc-section__head{display:flex;align-items:baseline;gap:10px;margin:0 0 14px}
.dsc-section__title{font-size:1.28rem;margin:0;letter-spacing:-.02em}
.dsc-section__more{margin-left:auto;font-size:.9rem;font-weight:600;text-decoration:none}

.dsc-grid{display:grid;gap:22px;grid-template-columns:1fr}
@media (min-width:700px){.dsc-grid{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1000px){.dsc-grid--3{grid-template-columns:repeat(var(--dsc-cols,3),1fr)}}

/* overlay cards — headline on the image with a category badge */
.dsc-card--overlay{position:relative;border-radius:var(--dsc-radius);overflow:hidden;min-height:280px;gap:0}
.dsc-card--overlay .dsc-card__media{position:absolute;inset:0;aspect-ratio:auto;border-radius:0}
.dsc-card--overlay>div{position:relative;z-index:1;margin-top:auto;padding:16px;color:#fff;background:linear-gradient(to top,rgba(8,10,14,.86),rgba(8,10,14,.55) 55%,transparent)}
.dsc-card--overlay .dsc-card__title a,.dsc-card--overlay .dsc-card__meta,.dsc-card--overlay .dsc-card__excerpt{color:#fff}
.dsc-card--overlay .dsc-card__meta{opacity:.85}
.dsc-card--overlay .dsc-card__badge{display:inline-block;font-size:.68rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;background:var(--dsc-accent);color:var(--dsc-accent-ink);padding:4px 9px;border-radius:5px;margin-bottom:9px;text-decoration:none}
/* Why this card is here: one signal per card in the exit panel. */
.dsc-card__flag{display:inline-flex;align-items:center;gap:5px;font-size:.7rem;font-weight:700;letter-spacing:.02em;padding:3px 8px;border-radius:999px;margin-bottom:7px;background:var(--dsc-ink-6,rgba(0,0,0,.05));color:var(--dsc-ink-2)}
.dsc-card__flag span{font-size:.82rem;line-height:1}
.dsc-card__flag--hot{background:rgba(255,96,32,.12);color:#c2410c}
.dsc-card__flag--exclusive{background:rgba(123,92,255,.12);color:#5b3fd6}
.dsc-card__flag--breaking{background:rgba(220,38,38,.11);color:#b91c1c}
.dsc-card__flag--pick{background:rgba(47,143,255,.12);color:#1d64c4}
.dsc-card--overlay.dsc-card--hero{min-height:420px}
@media (min-width:700px){.dsc-card--overlay.dsc-card--hero{flex-direction:column}.dsc-card--overlay.dsc-card--hero .dsc-card__media{flex:none}}

.dsc-card{display:flex;flex-direction:column;gap:10px;min-width:0}
.dsc-card__media{position:relative;display:block;border-radius:var(--dsc-radius);overflow:hidden;background:var(--dsc-bg-3);aspect-ratio:var(--dsc-card-ratio,16/9)}
.dsc-card__media img{width:100%;height:100%;object-fit:cover}
.dsc-card__src{display:flex;align-items:center;gap:7px;font-size:.8rem;color:var(--dsc-ink-3);font-weight:600}
.dsc-card__srcicon{width:20px;height:20px;border-radius:50%;background:var(--dsc-bg-3);display:grid;place-items:center;font-size:.7rem;color:var(--dsc-ink-2);flex:none;font-weight:700}
/* Titles and excerpts are clamped so every card in a row ends at the same
   height — a two-line headline next to a five-line one is what makes a grid
   look thrown together. */
.dsc-card__title{font-size:1.22rem;margin:0;line-height:1.25;font-weight:700;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.dsc-card__title a{color:var(--dsc-ink);text-decoration:none}
.dsc-card__title a:hover{text-decoration:underline}
.dsc-card__meta{display:flex;align-items:center;gap:8px;font-size:.84rem;color:var(--dsc-ink-3);margin-top:auto;padding-top:2px}

/* Hover: the image lifts inside its own frame, the headline picks up the accent.
   Transform and colour only — nothing here can move the card itself, so a row
   of cards never reflows under the cursor. */
.dsc-card__media img{transition:transform .45s cubic-bezier(.2,.6,.2,1)}
@media (hover:hover){
	.dsc-card:hover .dsc-card__media img{transform:scale(1.04)}
	.dsc-card:hover .dsc-card__title a{color:var(--dsc-accent);text-decoration:none}
}

/* Cards fade in as they arrive. Never applied above the fold: the first screen
   holds the LCP image, and starting it at opacity 0 delays the metric by exactly
   the length of this animation. app.js adds the class from the fifth card down. */
.dsc-reveal{opacity:0;transform:translateY(22px);filter:blur(5px);transition:opacity .6s ease,transform .6s ease,filter .6s ease}
.dsc-reveal.is-in{opacity:1;transform:none;filter:none}
@media (prefers-reduced-motion:reduce){.dsc-reveal{opacity:1;transform:none;filter:none;transition:none}}
.dsc-card__excerpt{margin:0;font-size:.96rem;color:var(--dsc-ink-2);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.dsc-card>div{display:flex;flex-direction:column;gap:6px;flex:1;min-width:0}
.dsc-card--hero .dsc-card__title{font-size:calc(1.72rem * var(--dsc-title-scale));-webkit-line-clamp:4}
.dsc-card--hero .dsc-card__media{aspect-ratio:4/3}
@media (min-width:700px){
	.dsc-card--hero{grid-column:1/-1;flex-direction:row;gap:24px;align-items:center}
	.dsc-card--hero .dsc-card__media{flex:0 0 55%;aspect-ratio:16/9}
	.dsc-card--hero>div{flex:1;justify-content:center;gap:10px}
	.dsc-card--hero .dsc-card__meta{margin-top:4px}
}

/* homepage top block layouts */
.dsc-top .dsc-grid{gap:22px;align-items:stretch}
.dsc-top .dsc-card{height:100%}
@media (min-width:700px){
	.dsc-top--mosaic .dsc-grid{grid-template-columns:2fr 1fr}
	.dsc-top--mosaic .dsc-card:first-child{grid-row:span 2}
	.dsc-top--mosaic .dsc-card--overlay:first-child{min-height:100%}
}
.dsc-intro{max-width:var(--dsc-wrap);margin:26px auto 30px;text-align:center}
.dsc-intro p{font-family:var(--dsc-font-head);font-size:1.25rem;line-height:1.4;color:var(--dsc-ink)}
.dsc-intro p+p{font-family:var(--dsc-font-body);font-size:1rem;color:var(--dsc-ink-2)}
.dsc-footer__text{max-width:var(--dsc-wrap);margin:0 auto 14px;text-align:center;font-size:.9rem}

/* compact list row (What to read next / drawer of related) */
.dsc-row{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-bottom:1px solid var(--dsc-line)}
.dsc-row:last-child{border-bottom:0}
.dsc-row__media{flex:0 0 96px;border-radius:var(--dsc-radius-sm);overflow:hidden;aspect-ratio:1/1;background:var(--dsc-bg-3)}
.dsc-row__media img{width:100%;height:100%;object-fit:cover}
.dsc-row__title{font-size:1.02rem;font-weight:700;margin:0;line-height:1.3;font-family:var(--dsc-font-head)}
.dsc-row__title a{color:var(--dsc-ink);text-decoration:none}
.dsc-row__meta{font-size:.78rem;color:var(--dsc-ink-3);margin-top:4px}

/* horizontal carousel (Trending stories / Beeps) */
.dsc-carousel-wrap{position:relative}
.dsc-carousel__btn{position:absolute;top:var(--dsc-arrow-top,38%);transform:translateY(-50%);z-index:2;width:44px;height:44px;border-radius:50%;border:1px solid var(--dsc-line);background:var(--dsc-bg);color:var(--dsc-ink);box-shadow:var(--dsc-shadow);cursor:pointer;display:grid;place-items:center}
.dsc-carousel__btn:hover{background:var(--dsc-bg-2)}
.dsc-carousel__btn svg{width:22px;height:22px}
.dsc-carousel__btn.is-prev{left:-14px}
.dsc-carousel__btn.is-next{right:-14px}
.dsc-carousel{display:grid;grid-auto-flow:column;grid-auto-columns:76%;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;padding-bottom:4px;overscroll-behavior-x:contain}
.dsc-carousel::-webkit-scrollbar{display:none}
.dsc-carousel>*{scroll-snap-align:start}
@media (min-width:700px){.dsc-carousel{grid-auto-columns:38%}}
@media (min-width:1000px){.dsc-carousel{grid-auto-columns:26%}}
.dsc-trend{display:flex;flex-direction:column;border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);overflow:hidden;background:var(--dsc-bg)}
.dsc-trend__media{display:block;aspect-ratio:16/9;background:var(--dsc-bg-3)}
.dsc-trend__media img{width:100%;height:100%;object-fit:cover}
/* Two clamped lines keep every card the same height and stop the headline
   being pushed out of view by a tall image. */
.dsc-trend__body{display:flex;flex-direction:column;gap:5px;padding:11px 12px 13px;flex:1}
.dsc-trend__title{font-size:.95rem;font-weight:700;margin:0;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.dsc-trend__title a{color:var(--dsc-ink);text-decoration:none}
.dsc-trend__views{font-size:.74rem;color:var(--dsc-ink-3);margin-top:auto;display:flex;gap:6px;align-items:center}

/* ==========================================================================
   5. Single article
   ========================================================================== */
.dsc-article{padding-top:18px}
.dsc-article+.dsc-article{border-top:10px solid var(--dsc-bg-2);margin-top:34px;padding-top:26px}
.dsc-eyebrow{display:inline-block;font-size:.74rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--dsc-accent-ink);background:var(--dsc-accent);padding:4px 9px;border-radius:5px;text-decoration:none;margin-bottom:12px}
/* The tight tracking is a desktop refinement; at phone sizes it just makes the
   letters collide. */
.dsc-title{font-size:calc(2.05rem * var(--dsc-title-scale));font-weight:800;line-height:1.14;margin:0 0 12px;letter-spacing:-.012em;hyphens:auto}
@media (min-width:700px){.dsc-title{letter-spacing:-.025em;line-height:1.1;hyphens:manual}}
@media (min-width:700px){.dsc-title{font-size:calc(2.65rem * var(--dsc-title-scale))}}
.dsc-dek{font-size:1.08rem;color:var(--dsc-ink-2);margin:0 0 16px;line-height:1.45}
.dsc-byline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:.87rem;color:var(--dsc-ink-3);margin-bottom:16px}
.dsc-byline__avatar img{border-radius:50%}
.dsc-byline strong{color:var(--dsc-ink)}
.dsc-byline a{color:var(--dsc-ink);text-decoration:none;font-weight:600}
.dsc-byline .sep{opacity:.5}
.dsc-hero{position:relative;margin:0 0 8px;border-radius:var(--dsc-radius);overflow:hidden;background:var(--dsc-bg-3)}
/* On the image the accent slab is too loud — a small dark pill instead, readable
   over any photo without shouting over the headline.

   No backdrop-filter: this sits on top of the lead image, which is the LCP
   element on every article. A blur here forces the browser to composite that
   region before it can paint it, and on a mid-range phone that showed up as
   several hundred milliseconds of LCP. A flat, slightly darker fill looks the
   same at this size. */
.dsc-eyebrow--onhero{position:absolute;left:12px;bottom:12px;margin:0;max-width:calc(100% - 24px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
	font-size:.68rem;font-weight:700;letter-spacing:.05em;padding:4px 10px;border-radius:999px;
	color:#fff;background:rgba(12,14,18,.78)}
.dsc-hero img{width:100%;height:auto}
.dsc-caption{font-size:.79rem;color:var(--dsc-ink-3);margin:8px 0 20px}

.dsc-body{font-size:var(--dsc-body-size)}
.dsc-body>h2{font-size:calc(1.55rem * var(--dsc-title-scale));font-weight:800;scroll-margin-top:calc(var(--dsc-header-real,var(--dsc-header-h)) + 60px)}
.dsc-body>h3{font-size:1.22rem;font-weight:700;scroll-margin-top:calc(var(--dsc-header-real,var(--dsc-header-h)) + 60px)}
.dsc-body img{border-radius:var(--dsc-radius-sm)}

/* oEmbeds: the wrapper reserves 16/9 up front (zero layout shift) and the
   player is stretched to fill it — an iframe keeps its own 560x315 otherwise
   and spills past the edge. */
.dsc-embed{display:block;position:relative;width:100%;aspect-ratio:16/9;margin:0 0 1.2em;border-radius:var(--dsc-radius-sm);overflow:hidden;background:var(--dsc-bg-3)}
.dsc-embed>iframe,.dsc-embed>video,.dsc-embed>object,.dsc-embed>embed{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none;border:0}
/* Core's responsive-embed support adds its own ratio box (a ::before with
   padding-top plus absolutely positioned iframes) around the same embed. Two
   ratio systems nested inside each other is what squashed the player: ours owns
   the ratio, core's is switched off here. */
.wp-block-embed__wrapper:has(.dsc-embed)::before{content:none}
.wp-block-embed:has(.dsc-embed) .wp-block-embed__wrapper{padding:0;position:static}
.wp-block-embed:has(.dsc-embed){margin-block:0 1.2em}
.wp-embed-aspect-4-3 .dsc-embed{aspect-ratio:4/3}
.wp-embed-aspect-1-1 .dsc-embed{aspect-ratio:1/1}
.wp-embed-aspect-21-9 .dsc-embed{aspect-ratio:21/9}
.wp-embed-aspect-9-16 .dsc-embed{aspect-ratio:9/16;max-width:420px;margin-inline:auto}
/* A raw <iframe> pasted into the editor (or injected by another plugin) never
   passes through the oEmbed filter, so it keeps width=560 height=315. Scaling
   the width without the height is exactly what squashes the player. */
.dsc-body iframe{width:100%;height:auto;aspect-ratio:16/9}
.dsc-body figure.wp-block-embed iframe{width:100%}
.dsc-body figcaption{font-size:.79rem;color:var(--dsc-ink-3);margin-top:6px}
.dsc-body a{color:var(--dsc-accent);font-weight:600}
.dsc-body ul,.dsc-body ol{padding-left:1.25em}
.dsc-body li{margin-bottom:.4em}

/* read-more collapse (AP style) */
.dsc-collapse{position:relative}
.dsc-collapse[data-collapsed]{max-height:var(--dsc-collapse-h,60vh);overflow:hidden}
/* The fade has to be opaque well before the clip line, otherwise the last
   visible line of text gets sliced in half. */
/* Reaches solid background well before the cut, so the half-line the crop leaves
   behind is never visible. */
.dsc-collapse[data-collapsed]::after{content:"";position:absolute;left:0;right:0;bottom:0;height:260px;background:linear-gradient(to bottom,transparent,var(--dsc-bg) 52%,var(--dsc-bg));pointer-events:none}
.dsc-readmore{display:flex;justify-content:center;margin:10px 0 26px;position:relative;z-index:1}
/* While the body is folded the button sits over the faded tail instead of below
   the crop — otherwise it lands against a chopped heading and reads as if it is
   covering the text. */
.dsc-collapse[data-collapsed] + .dsc-readmore,
.dsc-collapse[data-collapsed] ~ .dsc-readmore{margin-top:-64px}
.dsc-readmore button{display:inline-flex;align-items:center;gap:9px;background:var(--dsc-ink);color:var(--dsc-bg);border:0;border-radius:999px;padding:14px 26px;font-weight:800;font-size:1rem;cursor:pointer;box-shadow:var(--dsc-shadow)}
.dsc-readmore button:hover{opacity:.9}
.dsc-readmore svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.4;transition:transform .2s}
.dsc-readmore button[aria-expanded=true] svg{transform:rotate(180deg)}

/* AI summary — Quick Read (NDTV) / Need to know (People) */
.dsc-summary{border-radius:var(--dsc-radius);padding:2px;margin:20px 0 24px;background:linear-gradient(120deg,#7b5cff,#2f8fff 45%,#00c2a8)}
.dsc-summary__in{background:var(--dsc-bg);border-radius:calc(var(--dsc-radius) - 2px);padding:16px 16px 14px}
.dsc-summary__head{display:flex;align-items:center;gap:9px;width:100%;background:none;border:0;padding:0;margin:0;cursor:pointer;text-align:start;font:inherit;color:inherit}
.dsc-summary__head[aria-expanded=true]{margin-bottom:10px}
.dsc-summary__spark{width:22px;height:22px;flex:none}
.dsc-summary__label{font-weight:800;font-size:1.02rem;background:linear-gradient(90deg,#7b5cff,#2f8fff);-webkit-background-clip:text;background-clip:text;color:transparent}
.dsc-summary__note{font-size:.74rem;color:var(--dsc-ink-3);display:block;font-weight:400;margin:10px 0 0}
/* The first point, showing through the closed card. Two lines maximum: this is
   the hook, not the summary — it has to end mid-thought to be worth a tap. */
.dsc-summary__peek{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-top:3px;font-size:.88rem;font-weight:400;line-height:1.4;color:var(--dsc-ink-2)}
.dsc-summary__head[aria-expanded=true] .dsc-summary__peek{display:none}
.dsc-summary__toggle{margin-left:auto;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;background:none;border:0;cursor:pointer;color:var(--dsc-ink-3);padding:0}
.dsc-summary__toggle svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;transition:transform .2s}
/* The chevron flips when the card opens. The gift does not — it is a picture of
   a box, not an arrow, and a box turned upside down is just a box upside down. */
.dsc-summary__head[aria-expanded=true] .dsc-summary__toggle:not(.dsc-summary__toggle--gift) svg{transform:rotate(180deg)}
.dsc-summary__toggle--gift{color:var(--dsc-accent)}
.dsc-summary__toggle--gift>svg{transition:none}
/* Alive, but not frantic: a pulse every couple of seconds with a shake on top of
   it. Something that moves without stopping reads as a broken element; something
   that moves now and then reads as an invitation. */
.dsc-summary__head[aria-expanded=false] .dsc-summary__toggle--gift>svg{
	animation:dsc-gift-wiggle 2.6s ease-in-out infinite,dsc-gift-glow 2.6s ease-in-out infinite;
	transform-origin:50% 85%}
.dsc-summary__shut{display:none;line-height:0}
.dsc-summary__head[aria-expanded=true] .dsc-summary__toggle--gift>svg{display:none}
.dsc-summary__head[aria-expanded=true] .dsc-summary__shut{display:inline-flex;color:var(--dsc-ink-3)}
@keyframes dsc-gift-wiggle{
	0%,58%,100%{transform:rotate(0) scale(1)}
	63%{transform:rotate(-12deg) scale(1.16)}
	70%{transform:rotate(11deg) scale(1.16)}
	77%{transform:rotate(-7deg) scale(1.09)}
	84%{transform:rotate(5deg) scale(1.05)}
	91%{transform:rotate(0) scale(1)}}
@keyframes dsc-gift-glow{0%,55%,100%{opacity:.85}62%,86%{opacity:1}}
@media (prefers-reduced-motion:reduce){.dsc-summary__toggle--gift>svg{animation:none!important}}
/* A line the reveal has not reached yet has no text, so its bullet must not show
   either — three stray markers under the first sentence read as a broken list. */
.dsc-summary ul[data-typing] li:empty{display:none}
/* Caret rides the line being typed out; it disappears with the last character. */
.dsc-summary li[data-cursor]::after{content:"";display:inline-block;width:2px;height:1em;margin-left:2px;background:#7b5cff;vertical-align:-.14em;animation:dsc-caret 1s steps(1) infinite}
@keyframes dsc-caret{50%{opacity:0}}
@media (prefers-reduced-motion:reduce){.dsc-summary li[data-cursor]::after{display:none}}
.dsc-summary ul{margin:0;padding-left:1.15em}
.dsc-summary li{margin-bottom:.55em;color:var(--dsc-ink);font-size:1.01rem;line-height:1.45}
.dsc-summary li::marker{color:#7b5cff}
.dsc-summary[hidden]{display:none}
.dsc-summary__cta{margin:12px 0 0;padding-top:11px;border-top:1px solid var(--dsc-line)}
.dsc-summary__scroll{display:flex;align-items:center;gap:9px;font-size:.9rem;font-weight:700;color:var(--dsc-ink);text-decoration:none;line-height:1.3}
.dsc-summary__bang{flex:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:var(--dsc-accent);color:var(--dsc-accent-ink);font-size:.78rem;font-weight:800}
.dsc-summary__mins{display:block;margin-top:2px;font-size:.78rem;font-weight:500;color:var(--dsc-ink-3)}
.dsc-avatar{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;color:#fff;font-weight:700;line-height:1;letter-spacing:.02em;flex:none}
.dsc-summary__down{flex:none;margin-left:auto;display:inline-flex;color:var(--dsc-accent)}
.dsc-summary__down svg{fill:none;stroke:currentColor;stroke-width:2.2;animation:dsc-nudge 1.6s ease-in-out infinite}
@keyframes dsc-nudge{0%,100%{transform:translateY(-2px)}50%{transform:translateY(2px)}}
@media (prefers-reduced-motion:reduce){.dsc-summary__down svg{animation:none}}
/* The exit ramp for a summary-only reader: next story inside the card they are
   already looking at, not at the bottom of an article they will never reach. */
.dsc-hotnext{display:flex;align-items:center;gap:11px;margin:12px 0 0;padding:9px;border-radius:var(--dsc-radius);background:var(--dsc-bg-2);text-decoration:none;color:inherit}
.dsc-hotnext:hover{background:var(--dsc-bg-3)}
.dsc-hotnext__media{flex:none;width:66px;height:50px;border-radius:8px;overflow:hidden;display:block}
.dsc-hotnext__media img{width:100%;height:100%;object-fit:cover;display:block}
.dsc-hotnext__text{display:flex;flex-direction:column;gap:2px;min-width:0}
.dsc-hotnext__kicker{font-size:.68rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:#c2410c}
.dsc-hotnext__title{font-family:var(--dsc-font-head);font-weight:700;font-size:.94rem;line-height:1.28;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.dsc-hotnext__go{flex:none;margin-left:auto;color:var(--dsc-ink-3)}
.dsc-hotnext__go svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.2}
.dsc-summary__ask{margin:9px 0 0;font-size:.84rem;color:var(--dsc-ink-3)}
.dsc-summary__ask a{color:var(--dsc-accent);font-weight:600;text-decoration:none}
.dsc-summary__ask a:hover,.dsc-summary__scroll:hover span:not(.dsc-summary__bang){text-decoration:underline}
/* The recap belongs at the end of the story, so it stays out of sight while the
   body is still folded behind "Read More" — otherwise it lands mid-article,
   right under the fold, and reads like the article stopped there. */
.dsc-body[data-collapsed] ~ .dsc-summary--plain{display:none}
/* "NEED TO KNOW" variant — square hard-edged box, copied from People.com reference (IMG#13) */
.dsc-summary--plain{background:none;padding:0;border:2px solid var(--dsc-ink);border-radius:0}
.dsc-summary--plain .dsc-summary__in{border-radius:0}
.dsc-summary--plain .dsc-summary__label{background:none;color:var(--dsc-ink);-webkit-text-fill-color:currentColor;letter-spacing:.06em;text-transform:uppercase}

/* table of contents — H2 chips (In this story) */
.dsc-toc{border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);margin:0 0 22px;background:var(--dsc-bg)}
.dsc-toc__btn{width:100%;display:flex;align-items:center;gap:10px;background:none;border:0;padding:14px 16px;font-weight:800;font-size:1.05rem;cursor:pointer;text-align:start;font-family:var(--dsc-font-head)}
.dsc-toc__btn svg{margin-left:auto;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;transition:transform .2s}
.dsc-toc__btn[aria-expanded=true] svg{transform:rotate(180deg)}
.dsc-toc ol{list-style:none;margin:0;padding:0 16px 14px}
.dsc-toc li{margin:0}
.dsc-toc a{display:block;padding:9px 0;color:var(--dsc-ink);text-decoration:none;border-top:1px solid var(--dsc-line);font-size:1rem}
.dsc-toc a:hover{color:var(--dsc-accent)}
/* sticky H2 tab strip */
/* --dsc-header-real is the measured height of whatever is actually sticky
   (JS): with the menu on its own row the header is taller than the logo, and a
   fixed offset would slide this bar underneath it. */
/* Fixed, not sticky, and shown by sliding rather than by display:block. A
   sticky bar that appears mid-scroll adds ~45px to the flow and shoves the
   article down under the finger — that was the judder on mobile. */
.dsc-tocbar{position:fixed;left:0;right:0;top:var(--dsc-header-real,var(--dsc-header-h));z-index:30;background:var(--dsc-bg);border-bottom:1px solid var(--dsc-line);transform:translateY(-115%);transition:transform .18s ease;will-change:transform}
.dsc-tocbar[data-visible]{transform:none}
@media (prefers-reduced-motion:reduce){.dsc-tocbar{transition:none}}
/* Same track and the same 16px gutter as the header and the article, so the
   first tab starts exactly under the logo. */
.dsc-tocbar__in{display:flex;gap:0;overflow-x:auto;scrollbar-width:none;max-width:var(--dsc-wrap);margin-inline:auto;padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right))}
.dsc-tocbar__in::-webkit-scrollbar{display:none}
.dsc-tocbar a{flex:none;padding:11px 12px;font-size:.93rem;font-weight:700;color:var(--dsc-ink-3);text-decoration:none;border-bottom:3px solid transparent;white-space:nowrap}
/* The marker under the section you are in is the accent, not ink. Three pixels
   of pure black across a tab reads as a bar somebody left there by mistake —
   which is exactly what it was taken for — and it is the only black slab on a
   page whose every other marker is purple. */
.dsc-tocbar a[aria-current]{color:var(--dsc-ink);border-bottom-color:var(--dsc-accent)}

/* inline related card (cronista style) */
/* Beep feed. Phone: vertical, one card per screen, the short-video gesture.
   Desktop: the same cards laid out sideways, because a mouse wheel scrolls the
   page vertically and fighting it feels broken.

   dvh, not vh: on a phone the browser chrome collapses on scroll and vh would
   leave a slice of the next card showing at rest. */
.dsc-beepfeed{--dsc-beep-h:calc(100dvh - var(--dsc-header-real,56px));
	height:var(--dsc-beep-h);overscroll-behavior:contain;scrollbar-width:none;background:#0a0c10}
.dsc-beepfeed::-webkit-scrollbar{display:none}
.dsc-beepslide{position:relative;height:var(--dsc-beep-h);scroll-snap-align:start;scroll-snap-stop:always;
	display:flex;align-items:center;justify-content:center;overflow:hidden}

/* Phone: undo the horizontal carousel grid this container also carries, and give
   the feed the screen to itself.

   The page must not scroll behind it: with two scrollable areas stacked, a swipe
   that starts on a card ends up dragging the document, the snap point is lost
   and the gesture feels broken. The rail goes too — a beep is an app screen, not
   an article with a site around it. */
@media (max-width:899px){
	.dsc-beepfeed.dsc-carousel{display:block;overflow-x:hidden;overflow-y:auto;
		scroll-snap-type:y mandatory;padding-bottom:0;gap:0}
	.single-dsc_beep{overflow:hidden;overscroll-behavior:none}
	.single-dsc_beep .dsc-rail,
	.single-dsc_beep .dsc-masthead,
	.single-dsc_beep .dsc-footer{display:none}
	/* The bar keeps the logo, the theme switch and search — the way out. */
	.single-dsc_beep .dsc-header{position:static}
	.single-dsc_beep .dsc-brand{flex:none;overflow:visible}
}
/* Breadcrumb, share row and tag chips stay in the document for crawlers and
   screen readers, but a beep is an app screen — none of that page furniture
   belongs under the feed on any width. */
.single-dsc_beep .dsc-beepfoot{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* The card itself: picture, headline, source line, bullets, one way out. Reads
   as a card on the page's own background rather than white text burned over a
   photograph, which is what makes three bullets legible. */
.dsc-beepslide{align-items:center;justify-content:center;padding:14px}
.dsc-beepcard{display:flex;flex-direction:column;width:100%;max-width:440px;max-height:100%;overflow:hidden;
	background:var(--dsc-bg);color:var(--dsc-ink);border-radius:22px;box-shadow:0 10px 40px rgba(0,0,0,.28)}
.dsc-beepcard__media{margin:12px 12px 0;border-radius:14px;overflow:hidden;background:var(--dsc-bg-3);aspect-ratio:16/9;flex:none}
.dsc-beepcard__media img{width:100%;height:100%;object-fit:cover}
/* min-height:0 is the whole fix for the clipped buttons: a flex child refuses to
   shrink below its content by default, so the text block kept its full height,
   pushed the footer past the card edge and overflow:hidden cut it off. */
.dsc-beepcard__in{padding:16px 20px 20px;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
.dsc-beepcard__title{font-family:var(--dsc-font-head);font-size:clamp(1.22rem,4.4vw,1.5rem);line-height:1.22;margin:0 0 8px;color:var(--dsc-ink)}
.dsc-beepcard__meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin:0 0 14px;font-size:.8rem;color:var(--dsc-ink-3)}
.dsc-beepcard__cat{font-weight:700;color:var(--dsc-ink-2)}
.dsc-beepcard__info{position:relative;display:inline-flex;align-items:center;color:var(--dsc-ink-3);cursor:help}
.dsc-beepcard__info svg{stroke-width:1.8}
/* The tooltip is the same text the title attribute carries, shown where there is
   no hover to trigger the native one. */
.dsc-beepcard__tip{position:absolute;left:50%;bottom:calc(100% + 8px);transform:translateX(-50%);
	width:max-content;max-width:230px;padding:7px 10px;border-radius:8px;font-size:.72rem;line-height:1.35;
	background:var(--dsc-ink);color:var(--dsc-bg);opacity:0;visibility:hidden;transition:opacity .15s ease;z-index:2}
.dsc-beepcard__info:hover .dsc-beepcard__tip,.dsc-beepcard__info:focus .dsc-beepcard__tip{opacity:1;visibility:visible}
.dsc-beepcard__list{margin:0;padding:0;list-style:none;font-size:1rem;line-height:1.5;color:var(--dsc-ink-2)}
.dsc-beepcard__list li{position:relative;margin:0 0 12px;padding-left:18px}
.dsc-beepcard__list li::before{content:"";position:absolute;left:0;top:.55em;width:6px;height:6px;border-radius:50%;background:var(--dsc-accent)}
.dsc-beepcard__body{font-size:1rem;line-height:1.55;color:var(--dsc-ink-2)}
.dsc-beepcard__body p{margin:0 0 8px}
.dsc-beepcard__foot{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:18px}
.dsc-beepcard__cta{padding:11px 26px;border-radius:999px;
	background:var(--dsc-bg-2);color:var(--dsc-accent);font-weight:700;font-size:.95rem;text-decoration:none}
.dsc-beepcard__cta:hover{background:var(--dsc-accent);color:var(--dsc-accent-ink)}
.dsc-beepcard__share{display:inline-flex;align-items:center;gap:6px;padding:10px 16px;border:0;border-radius:999px;
	background:var(--dsc-bg-2);color:var(--dsc-ink-2);font-weight:700;font-size:.9rem;font-family:inherit;cursor:pointer}
.dsc-beepcard__share:hover{color:var(--dsc-ink)}
.dsc-beepcard__share svg{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* Ad slide: the ad centred on its own screen, nothing else competing with it. */
.dsc-beepslide--ad{align-items:center;justify-content:center;padding:20px}
.dsc-beepslide--ad .dsc-ad{width:100%;max-width:440px;margin:0;display:grid;place-items:center}
@media (min-width:900px){
	/* Desktop: the same phone-shaped card, paged sideways with the arrows the
	   carousel script adds. Snap points and the scrollbar-hiding come from
	   .dsc-carousel — only the size and the card height are set here.

	   One beep per view, same as the phone — three cards side by side meant three
	   slides were over the 60% mark at once, so every one of them rewrote the
	   address bar and the tab title ended up describing a different card than the
	   URL. A single slide per screen is also what makes the arrows mean "next
	   beep" instead of "scroll a bit". */
	.dsc-beepfeed{--dsc-beep-h:min(720px,calc(100dvh - 140px));
		max-width:460px;margin:24px auto;padding-inline:0;
		grid-auto-columns:100%;background:transparent}
	/* app.js wraps the feed in .dsc-carousel-wrap and hangs the arrows off it.
	   The wrapper is a plain div at full page width, so without this the buttons
	   sit at the window edges while the card is centred hundreds of px inside. */
	.dsc-carousel-wrap:has(> .dsc-beepfeed){max-width:460px;margin-inline:auto}
	.dsc-carousel-wrap > .dsc-beepfeed{margin-inline:0}
	/* Clear of the card rather than on top of it — the card has no dead margin to
	   hide a button in. Centred on the card, not on its picture: app.js aims the
	   arrows at the artwork, which on a full-height beep card is near the top. */
	.dsc-carousel-wrap:has(> .dsc-beepfeed) .dsc-carousel__btn{top:50%}
	.dsc-carousel-wrap:has(> .dsc-beepfeed) .dsc-carousel__btn.is-prev{left:-62px}
	.dsc-carousel-wrap:has(> .dsc-beepfeed) .dsc-carousel__btn.is-next{right:-62px}
	/* The slide clips on a phone because the card fills the screen. Here that
	   crop cut the card's own shadow into a rectangle at the slide edge. */
	.dsc-beepslide{overflow:visible;padding:6px}
	/* Full slide height, or the frame jumps size on every page depending on how
	   many bullets that beep has. The body scrolls inside a long one. */
	.dsc-beepcard{max-width:none;height:100%;border:1px solid var(--dsc-line);
		box-shadow:0 4px 18px rgba(12,16,24,.09)}
}

/* In-article strip: one block, swiped sideways. Sits in the text column, so it
   gets a rule above and below rather than a card frame — a second bordered box
   inside an article reads as an ad slot. */
.dsc-inlinestrip{margin:28px 0;padding:16px 0;border-top:1px solid var(--dsc-line);border-bottom:1px solid var(--dsc-line)}
.dsc-inlinestrip__lbl{margin:0 0 12px;font-size:.78rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--dsc-accent)}
/* Three fixed columns at every width, square thumbnails. Nothing scrolls and
   nothing is hidden behind a gesture — on a phone the three headlines simply run
   narrower and are clamped. */
.dsc-inlinegrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.dsc-inlinecard{display:flex;flex-direction:column;gap:8px;min-width:0;text-decoration:none;color:var(--dsc-ink)}
.dsc-inlinecard__media{display:block;aspect-ratio:1/1;border-radius:12px;overflow:hidden;background:var(--dsc-bg-3)}
.dsc-inlinecard__media img{width:100%;height:100%;object-fit:cover}
.dsc-inlinecard__title{font-family:var(--dsc-font-head);font-weight:700;font-size:.86rem;line-height:1.25;
	display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}
.dsc-inlinecard:hover .dsc-inlinecard__title{color:var(--dsc-accent)}
@media (min-width:700px){
	.dsc-inlinegrid{gap:18px}
	.dsc-inlinecard__title{font-size:.98rem;-webkit-line-clamp:3}
}

.dsc-inline{display:flex;gap:12px;align-items:center;border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);overflow:hidden;margin:26px 0;background:var(--dsc-bg-2);text-decoration:none}
.dsc-inline__media{flex:0 0 92px;aspect-ratio:1/1;background:var(--dsc-bg-3)}
.dsc-inline__media img{width:100%;height:100%;object-fit:cover}
.dsc-inline__txt{padding:10px 14px 10px 0;font-size:.98rem;color:var(--dsc-ink);line-height:1.35}
.dsc-inline__kicker{color:var(--dsc-accent);font-weight:800;margin-right:5px}

/* tag pills — Read More: */
/* FAQ accordion. No JS: <details name> is single-open on its own, and the row
   animation runs on ::details-content where the browser supports it — elsewhere
   it opens instantly, which is the correct fallback for a disclosure. */
.dsc-faq{margin:30px 0}
.dsc-faq__title{font-family:var(--dsc-font-head);font-size:1.32rem;margin:0 0 12px}
.dsc-faq__item{border-top:1px solid var(--dsc-line);interpolate-size:allow-keywords}
.dsc-faq__item:last-of-type{border-bottom:1px solid var(--dsc-line)}
.dsc-faq__q{display:flex;align-items:center;justify-content:space-between;gap:14px;
	padding:15px 2px;font-family:var(--dsc-font-head);font-weight:700;font-size:1.02rem;
	line-height:1.35;color:var(--dsc-ink);cursor:pointer;list-style:none}
.dsc-faq__q::-webkit-details-marker{display:none}
.dsc-faq__q:hover{color:var(--dsc-accent)}
.dsc-faq__q svg{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;
	stroke-linecap:round;stroke-linejoin:round;transition:transform .25s ease}
.dsc-faq__item[open] .dsc-faq__q svg{transform:rotate(180deg)}
.dsc-faq__a{margin:0;padding:0 2px 16px;color:var(--dsc-ink-2);line-height:1.6}
.dsc-faq__item::details-content{block-size:0;overflow:hidden;
	transition:block-size .28s ease,content-visibility .28s allow-discrete}
.dsc-faq__item[open]::details-content{block-size:auto}
@media (prefers-reduced-motion:reduce){
	.dsc-faq__item::details-content{transition:none}
	.dsc-faq__q svg{transition:none}
}

.dsc-tags{display:flex;flex-wrap:wrap;gap:9px;align-items:center;margin:24px 0}
.dsc-tags__label{font-family:var(--dsc-font-head);font-weight:700;font-size:1.05rem;margin-right:2px}
.dsc-tag{display:inline-block;border:1.5px solid var(--dsc-ink);border-radius:999px;padding:7px 16px;font-size:.92rem;color:var(--dsc-ink);text-decoration:none;line-height:1.3}
.dsc-tag:hover{background:var(--dsc-ink);color:var(--dsc-bg)}
.dsc-tag--solid{background:var(--dsc-bg-3);border-color:transparent}
.dsc-tag--accent{border-color:var(--dsc-accent);color:var(--dsc-accent)}
.dsc-tag--accent:hover{background:var(--dsc-accent);color:var(--dsc-accent-ink)}

/* reactions */
.dsc-react{border:1px solid var(--dsc-line);background:var(--dsc-bg-2);border-radius:var(--dsc-radius);padding:14px;margin:26px 0}
.dsc-react__q{font-weight:700;margin:0 0 12px;font-size:1rem;display:flex;align-items:center;gap:8px}
/* Buttons keep their own size and wrap; stretching five of them across a narrow
   phone made the row look pulled apart. */
.dsc-react__list{display:flex;flex-wrap:wrap;justify-content:center;gap:6px;margin:0;padding:0;list-style:none}
.dsc-react__list>li{flex:0 1 92px}
.dsc-react__btn{display:flex;flex-direction:column;align-items:center;gap:5px;background:none;border:0;cursor:pointer;padding:8px 4px;border-radius:var(--dsc-radius-sm);width:100%;min-width:0}
.dsc-react__btn:hover{background:var(--dsc-bg-3)}
.dsc-react__btn[aria-pressed=true]{background:var(--dsc-bg-3);box-shadow:inset 0 0 0 2px var(--dsc-accent)}
.dsc-react__emoji{font-size:1.85rem;line-height:1;transition:transform .15s}
.dsc-react__btn:hover .dsc-react__emoji{transform:scale(1.16)}
.dsc-react__lbl{font-size:.75rem;color:var(--dsc-ink-3);text-align:center;line-height:1.15}
.dsc-react__count{font-size:.74rem;font-weight:700;color:var(--dsc-ink-2)}
.dsc-react__thanks{font-size:.85rem;color:var(--dsc-ink-3);margin:10px 0 0}

/* reaction pill bar (above the lead image) */
.dsc-pills{position:relative;margin:0 0 16px}
.dsc-pills__list{display:flex;flex-wrap:wrap;gap:6px;list-style:none;margin:0;padding:0}
/* Beats the .dsc-react__btn sizing the same element also carries. */
.dsc-pills__list>li{flex:0 0 auto}
.dsc-pills .dsc-pill{flex:0 0 auto;width:auto}
/* flex-direction and flex are reset because the pill also carries .dsc-react__btn,
   which stacks its children for the big end-of-article block. */
.dsc-pill{display:inline-flex;flex-direction:row;flex:0 0 auto;align-items:center;gap:6px;height:40px;padding:0 13px;border:1px solid var(--dsc-line);background:var(--dsc-bg-2);border-radius:999px;cursor:pointer;font-size:.85rem;line-height:1;color:var(--dsc-ink)}
.dsc-pill:hover{border-color:var(--dsc-ink-3);background:var(--dsc-bg-3)}
.dsc-pill__emoji{font-size:1.15rem;line-height:1}
.dsc-pill__count{font-weight:700;font-variant-numeric:tabular-nums;color:var(--dsc-ink-2)}
.dsc-pill__count:empty{display:none}
.dsc-pill--more{color:var(--dsc-ink-3);gap:5px}
.dsc-pill__label{font-weight:600}

/* One reaction per visitor: after voting the choice stays lit and the rest
   stop responding, instead of silently doing nothing on click. */
.dsc-pill[aria-pressed=true]{background:var(--dsc-accent);border-color:var(--dsc-accent);color:var(--dsc-accent-ink)}
.dsc-pill[aria-pressed=true] .dsc-pill__count{color:inherit}
/* Voting never locks the row: readers change their mind and the server moves the
   vote instead of counting a second one. */
.dsc-pills[data-voted] .dsc-pill:not([aria-pressed=true]){opacity:1}

/* Picker floats under the "more" chip rather than pushing the page around. */
.dsc-pills__picker{position:absolute;top:calc(100% + 8px);left:0;z-index:20;display:flex;flex-wrap:wrap;gap:4px;max-width:min(420px,92vw);padding:8px;border:1px solid var(--dsc-line);border-radius:16px;background:var(--dsc-bg);box-shadow:var(--dsc-shadow)}
.dsc-pills__pick{position:relative;display:grid;place-items:center;width:44px;height:44px;border:0;background:none;border-radius:12px;cursor:pointer;font-size:1.4rem;line-height:1}
.dsc-pills__pick:hover{background:var(--dsc-bg-2)}
.dsc-pills__pick[aria-pressed=true]{background:var(--dsc-bg-3);box-shadow:inset 0 0 0 2px var(--dsc-accent)}
.dsc-pills__pick .dsc-pill__emoji{font-size:1.4rem}
.dsc-pills__pick .dsc-pill__count{position:absolute;right:2px;bottom:1px;font-size:.65rem;color:var(--dsc-ink-3)}

/* share row */
.dsc-share{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:22px 0}
.dsc-share__lbl{font-size:.82rem;font-weight:700;color:var(--dsc-ink-3);text-transform:uppercase;letter-spacing:.06em}
.dsc-share a,.dsc-share button{display:inline-grid;place-items:center;width:42px;height:42px;border-radius:11px;border:1.5px solid var(--dsc-line);background:var(--dsc-bg);cursor:pointer;color:var(--dsc-ink)}
.dsc-share a:hover,.dsc-share button:hover{border-color:currentColor}
.dsc-share svg{width:20px;height:20px}
.dsc-share .is-fb{color:#1877f2}.dsc-share .is-x{color:var(--dsc-ink)}.dsc-share .is-wa{color:#25d366}
.dsc-share .is-tg{color:#2aabee}.dsc-share .is-pin{color:#e60023}.dsc-share .is-gn{color:#4285f4}

/* sticky bottom share bar (mobile, cronista) */
.dsc-stickybar{position:fixed;left:0;right:0;bottom:0;z-index:45;background:var(--dsc-bg);border-top:1px solid var(--dsc-line);display:flex;align-items:center;gap:10px;padding:8px 12px;transform:translateY(110%);transition:transform .22s ease;padding-bottom:calc(8px + env(safe-area-inset-bottom))}
.dsc-stickybar[data-visible]{transform:none}
.dsc-stickybar__title{flex:1;min-width:0;font-size:.85rem;font-weight:700;line-height:1.25;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media (min-width:900px){.dsc-stickybar{display:none}}

/* author box */
.dsc-author{display:flex;gap:14px;border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);padding:16px;margin:30px 0;background:var(--dsc-bg-2)}
.dsc-author__avatar{flex:none}
.dsc-author__avatar img{border-radius:50%}
.dsc-author__name{font-size:1.06rem;font-weight:800;margin:0 0 2px;font-family:var(--dsc-font-head)}
.dsc-author__name a{color:var(--dsc-ink);text-decoration:none}
.dsc-author__role{font-size:.76rem;color:var(--dsc-ink-3);text-transform:uppercase;letter-spacing:.06em;font-weight:700;margin:0 0 7px}
.dsc-author__bio{font-size:.93rem;color:var(--dsc-ink-2);margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.dsc-author__bio[data-open]{-webkit-line-clamp:unset;display:block}
.dsc-author__more{margin-top:4px;padding:0;border:0;background:none;cursor:pointer;font-size:.85rem;font-weight:700;color:var(--dsc-accent);text-decoration:underline;text-underline-offset:3px}
.dsc-author__links{display:flex;gap:12px;margin-top:8px;font-size:.85rem}

/* google news / subscribe CTA */
/* Gradient ring via two background layers: the flat fill is clipped to the
   padding box, the moving gradient to the border box. A pseudo-element with a
   negative z-index would paint over the fill, not behind it. */
/* Beeps banner under the comments. The colour is in the ring, not in the plate —
   same two-layer trick as the Google News card above and the same hues as the
   Quick Read frame, so the two AI blocks on the page read as one family.
   Text sits centred; the arrow is taken out of the flow so it does not pull the
   block off centre. */
.dsc-beepscta{position:relative;display:flex;align-items:center;justify-content:center;text-align:center;
	gap:14px;margin:26px 0;padding:16px 46px;text-decoration:none;color:var(--dsc-ink);
	border:2px solid transparent;border-radius:var(--dsc-radius);
	background:linear-gradient(var(--dsc-bg),var(--dsc-bg)) padding-box,
		linear-gradient(120deg,#7b5cff,#2f8fff 45%,#00c2a8) border-box;
	background-size:auto,180% 100%}
.dsc-beepscta:hover{background-position:0 0,100% 0}
@media (prefers-reduced-motion:no-preference){.dsc-beepscta{transition:background-position .5s ease,transform .2s ease}}
.dsc-beepscta:active{transform:scale(.99)}
.dsc-beepscta__in{display:flex;flex-direction:column;gap:3px;min-width:0}
.dsc-beepscta__title{font-family:var(--dsc-font-head);font-weight:800;font-size:1.12rem;line-height:1.2;color:var(--dsc-accent)}
.dsc-beepscta__txt{font-size:.92rem;color:var(--dsc-ink-3)}
.dsc-beepscta__arrow{position:absolute;right:18px;top:50%;transform:translateY(-50%);font-size:1.3rem;line-height:1;color:var(--dsc-ink-3)}

/* The moving border is two layers, not an animated background-position: a
   background-position keyframe repaints the whole box every frame on the main
   thread, a translate runs on the compositor. ::before is the gradient ribbon
   (two seamless tiles wide), ::after is the card face that covers all but the
   2px ring. */
.dsc-gnews{position:relative;isolation:isolate;overflow:hidden;
	display:flex;align-items:center;gap:12px;padding:16px 18px;margin:24px 0;text-decoration:none;color:var(--dsc-ink);
	border-radius:var(--dsc-radius)}
.dsc-gnews::before{content:"";position:absolute;top:0;left:0;height:100%;width:600%;z-index:-2;
	background:linear-gradient(90deg,#4285f4,#ea4335,#fbbc05,#34a853,#4285f4) 0 0/50% 100% repeat-x;
	animation:dsc-slide 8s linear infinite}
.dsc-gnews::after{content:"";position:absolute;inset:2px;z-index:-1;
	border-radius:calc(var(--dsc-radius) - 2px);background:var(--dsc-bg)}
@keyframes dsc-slide{to{transform:translate3d(-50%,0,0)}}
@media (prefers-reduced-motion:reduce){.dsc-gnews::before{animation:none}}
/* The Google News mark carries its own colours, so it needs a light plate even
   in dark mode — Google's brand colours on a dark card go muddy. */
.dsc-gnews__icon{width:42px;height:42px;border-radius:11px;background:#fff;box-shadow:inset 0 0 0 1px var(--dsc-line);display:grid;place-items:center;flex:none}
.dsc-gnews__icon svg{width:26px;height:26px}
.dsc-gnews__kicker{font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dsc-ink-3);font-weight:700}
.dsc-gnews__txt{font-weight:800}
.dsc-gnews__arrow{margin-left:auto;font-size:1.3rem;color:var(--dsc-ink-2)}

.dsc-toast{position:fixed;left:50%;bottom:calc(18px + env(safe-area-inset-bottom));transform:translate(-50%,14px);z-index:90;max-width:min(92vw,420px);padding:11px 16px;border-radius:12px;background:var(--dsc-ink);color:var(--dsc-bg);font-size:.9rem;font-weight:600;box-shadow:var(--dsc-shadow);opacity:0;pointer-events:none;transition:opacity .18s,transform .18s}
.dsc-toast[data-open]{opacity:1;transform:translate(-50%,0)}

/* discovery feed — shown once, at the end of the article. Deliberately small:
   it is a suggestion, not a takeover. */
/* No scrolling inside the sheet: it showed four cards in a box two and a half
   cards tall, so the bottom row was always sliced and the panel read as broken.
   The sheet now shows whole cards only — the rule below drops any past the
   fourth rather than clipping one halfway. */
.dsc-feedpanel{position:fixed;left:0;right:0;bottom:0;max-width:560px;margin-inline:auto;max-height:min(74vh,560px);z-index:70;background:var(--dsc-bg);border:1px solid var(--dsc-line);border-bottom:0;border-radius:18px 18px 0 0;box-shadow:0 -6px 28px rgba(8,12,20,.18);transform:translateY(102%);transition:transform .28s cubic-bezier(.2,.8,.25,1);overflow:hidden;overscroll-behavior:contain;padding:0 14px 18px}
/* Cards inside the sheet are a browse list, not the article feed — two per row
   at most, headline-first, so the sheet stays short. */
.dsc-feedpanel .dsc-grid{grid-template-columns:1fr 1fr;gap:12px}
.dsc-feedpanel .dsc-grid>:nth-child(n+5){display:none}
.dsc-feedpanel .dsc-card{gap:7px}
.dsc-feedpanel .dsc-card__media{aspect-ratio:16/9}
.dsc-feedpanel .dsc-card__title{font-size:.92rem;line-height:1.28;-webkit-line-clamp:2}
/* Date and read time stay — they are what tells the reader the story is fresh.
   Two title lines instead of three already buys back more height than the meta
   line costs, so the sheet fits without dropping them. */
.dsc-feedpanel .dsc-card__meta{font-size:.74rem;padding-top:0;margin-top:2px}
.dsc-feedpanel .dsc-card--hero{grid-column:auto;flex-direction:column}
.dsc-feedpanel[data-open]{transform:none}
.dsc-feedpanel__grip{width:36px;height:4px;border-radius:2px;background:var(--dsc-line);margin:9px auto 2px}
.dsc-feedpanel__head{display:flex;align-items:center;gap:8px;position:sticky;top:0;background:var(--dsc-bg);padding:6px 0 10px;z-index:1}
.dsc-feedpanel__head h2{margin:0;font-size:1rem}
.dsc-feedpanel__close{margin-left:auto}
/* On a mouse screen it sits in the corner instead of spanning the viewport. */
@media (min-width:900px){
	.dsc-feedpanel{left:auto;right:20px;bottom:20px;margin-inline:0;width:380px;max-height:64vh;border:1px solid var(--dsc-line);border-radius:16px;transform:translateY(calc(100% + 24px))}
	.dsc-feedpanel .dsc-grid{grid-template-columns:1fr}
	.dsc-feedpanel .dsc-card{flex-direction:row;align-items:flex-start;gap:10px}
	.dsc-feedpanel .dsc-card__media{flex:0 0 108px}
	.dsc-feedpanel .dsc-card>div{flex:1;min-width:0}
	.dsc-feedpanel__grip{display:none}
}

/* WP Rocket's "lazy rendering" stamps data-wpr-lazyrender on blocks below the
   fold and gives them `content-visibility:auto` with no contain-intrinsic-size.
   An unrendered block then measures zero, so the document keeps changing height
   as you scroll and the end of the article turns into a blank sheet you can
   scroll into. On this theme it lands on the 1px sentinel, one carousel and the
   footer — nothing that pays for the trouble. !important because the plugin
   prints its rule inline in the head, after this file.

   It also matters for the sticky share bar: content-visibility implies
   contain:layout paint, which makes a position:fixed child anchor to the
   contained block instead of the viewport. */
[data-wpr-lazyrender]{content-visibility:visible!important}

/* infinite feed helpers */
.dsc-sentinel{height:1px}
.dsc-loading{display:flex;justify-content:center;padding:26px 0}
.dsc-spinner{width:26px;height:26px;border:3px solid var(--dsc-line);border-top-color:var(--dsc-accent);border-radius:50%;animation:dsc-spin .7s linear infinite}
@keyframes dsc-spin{to{transform:rotate(360deg)}}
.dsc-nextup{display:flex;align-items:center;gap:10px;margin:34px 0 4px;color:var(--dsc-ink-3);font-size:.78rem;font-weight:800;letter-spacing:.14em;text-transform:uppercase}
.dsc-nextup::before,.dsc-nextup::after{content:"";height:1px;background:var(--dsc-line);flex:1}
.dsc-loadmore{display:block;margin:26px auto;background:var(--dsc-ink);color:var(--dsc-bg);border:0;border-radius:999px;padding:13px 30px;font-weight:800;cursor:pointer}

/* ==========================================================================
   6. Comments
   ========================================================================== */
/* Honeypot. Taken out of the layout rather than display:none — a bot that skips
   hidden inputs would skip the trap too. Nothing focusable, nothing announced. */
.dsc-trap{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.dsc-posted{margin:0 0 18px;padding:13px 15px;border-radius:var(--dsc-radius);background:var(--dsc-bg-2);border:1px solid var(--dsc-line);font-size:.92rem;color:var(--dsc-ink-2)}
/* A comment posted without a reload appears in place. It fades in rather than
   snapping into existence, because the page around it does not move and without
   the movement there is nothing to tell the reader their comment arrived. */
.dsc-comment--new{animation:dsc-comment-in .35s ease}
@keyframes dsc-comment-in{from{opacity:0;transform:translateY(8px)}}
@media (prefers-reduced-motion:reduce){.dsc-comment--new{animation:none}}

/* WordPress prints the cancel link inside the reply heading. Left unstyled it
   sits flush against the name it follows — "Antwoord op lila RosaReactie
   annuleren" reads as one broken word. Wrapping puts it on its own line as soon
   as the name is long, which on a phone is always. */
.comment-reply-title{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin:0 0 12px}
.comment-reply-title small{font-size:.62em;font-weight:400}
#cancel-comment-reply-link{color:var(--dsc-ink-3)}

.dsc-cform{margin:22px 0 0}
.dsc-cform__btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:16px 20px;border:0;border-radius:var(--dsc-radius);background:var(--dsc-accent);color:var(--dsc-accent-ink);font-family:var(--dsc-font-head);font-size:1.05rem;font-weight:800;cursor:pointer}
.dsc-cform__btn svg{fill:none;stroke:currentColor;stroke-width:2.4;transition:transform .2s}
.dsc-cform__btn[aria-expanded=true] svg{transform:rotate(180deg)}
.dsc-cform__btn:hover{filter:brightness(1.08)}
.dsc-cform__btn[aria-expanded=true]{margin-bottom:6px}
.dsc-comments{margin:34px 0 0}
.dsc-comments__title{font-size:1.25rem;margin:0 0 14px}
.dsc-clist{list-style:none;margin:0;padding:0}
.dsc-clist ol{list-style:none;margin:0;padding-left:34px}
.dsc-comment{padding:14px 0;border-bottom:1px solid var(--dsc-line)}
.dsc-comment__head{display:flex;align-items:center;gap:10px}
.dsc-comment__avatar img{border-radius:50%}
.dsc-comment__author{font-weight:700;font-size:.95rem}
.dsc-comment__badge{font-size:.68rem;font-weight:800;background:#d8f3dc;color:#14532d;border-radius:999px;padding:3px 9px;text-transform:none}
.dsc-comment__date{font-size:.78rem;color:var(--dsc-ink-3)}
.dsc-comment__text{margin:8px 0 8px;font-size:.98rem;color:var(--dsc-ink)}
.dsc-comment__actions{display:flex;align-items:center;gap:8px;font-size:.85rem}
.dsc-vote{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:36px;min-width:52px;border:1px solid var(--dsc-line);background:var(--dsc-bg);border-radius:999px;padding:5px 12px;cursor:pointer;color:var(--dsc-ink-2);font-size:.82rem;font-weight:700;line-height:1}
.dsc-vote:hover{border-color:var(--dsc-ink-3)}
/* A count of nothing is not a count. Left in the flow it was an empty box with
   a 6px gap in front of it, which pushed the thumb off centre — that is the
   lopsided pill, not the icon. */
.dsc-vote span:empty{display:none}
.dsc-vote span{font-variant-numeric:tabular-nums}
/* Agreement is green and disagreement is red once the reader has picked one.
   Both stay grey until then: two coloured buttons side by side on a comment
   nobody has voted on read as a verdict the site has already reached. */
.dsc-vote[data-dsc-vote=up][aria-pressed=true]{border-color:#2ea043;color:#2ea043;background:color-mix(in srgb,#2ea043 8%,var(--dsc-bg))}
.dsc-vote[data-dsc-vote=down][aria-pressed=true]{border-color:#e5484d;color:#e5484d;background:color-mix(in srgb,#e5484d 8%,var(--dsc-bg))}
@media (hover:hover){
	.dsc-vote[data-dsc-vote=up]:hover{border-color:#2ea043;color:#2ea043}
	.dsc-vote[data-dsc-vote=down]:hover{border-color:#e5484d;color:#e5484d}
}
/* block, so the 16px box is the glyph and not a line box with a descender gap
   under it — that half-pixel is what made the two thumbs sit at different
   heights next to each other. */
.dsc-vote svg{display:block;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.9}
.dsc-comment__reply{margin-left:auto;font-weight:700;text-decoration:none;color:var(--dsc-ink)}
/* Yours to take down. Quiet by default — it sits on every line the reader has
   ever written, and a red button on each of them reads as a warning about the
   comment rather than an offer. */
/* "Pinned", at the far end of the header line. margin-left:auto rather than a
   fixed position, so it sits against the right edge whatever the name beside it
   is doing. */
.dsc-comment__pinned{margin-left:auto;display:inline-flex;align-items:center;gap:4px;flex:none;font-size:.72rem;font-weight:700;color:var(--dsc-ink-3)}
.dsc-comment__pinned svg{display:block}
.dsc-comment.is-pinned{border-radius:var(--dsc-radius);background:color-mix(in srgb,var(--dsc-accent) 4%,var(--dsc-bg));padding:10px 12px;margin-left:-12px;margin-right:-12px}

/* The author's mark: their avatar with a heart on the corner of it. The heart
   carries a ring in the page colour so it stays legible over whatever the
   avatar happens to be — these are photographs, not flat shapes. */
.dsc-comment__alike{position:relative;flex:none;display:inline-flex;width:24px;height:24px;margin-right:2px}
.dsc-comment__alike img{width:24px;height:24px;border-radius:50%;display:block}
.dsc-comment__alike-heart{position:absolute;right:-3px;bottom:-3px;display:grid;place-items:center;width:14px;height:14px;border-radius:50%;background:#e5484d;color:#fff;box-shadow:0 0 0 2px var(--dsc-bg)}
.dsc-comment__alike-heart svg{display:block;fill:currentColor}

/* Moderator buttons, quieter than Delete: these are reversible and Delete is
   not, so they have no business shouting louder than it. */
.dsc-comment__mod{order:8;padding:2px 0;border:0;background:none;font:inherit;font-size:.85rem;color:var(--dsc-ink-3);text-decoration:underline;cursor:pointer}
.dsc-comment__mod:hover{color:var(--dsc-accent)}
.dsc-comment__mod:disabled{opacity:.5;cursor:default}

.dsc-comment__del{order:9;padding:2px 0;border:0;background:none;font:inherit;font-size:.85rem;color:var(--dsc-ink-3);text-decoration:underline;cursor:pointer}
.dsc-comment__del:hover{color:#e5484d}
.dsc-comments__wipe{display:block;margin:0 0 14px;padding:2px 0;border:0;background:none;font:inherit;font-size:.85rem;color:var(--dsc-ink-3);text-decoration:underline;cursor:pointer}
.dsc-comments__wipe:hover{color:#e5484d}
/* Waiting for the second tap — see arm(). */
.dsc-comment__del.is-armed,.dsc-comments__wipe.is-armed{color:#e5484d;font-weight:700}

/* A reply used to be nothing but an indent, which on a phone reads as a
   crooked comment rather than an answer to the one above it. A rail down the
   thread, a tick into each reply and a tint of its own say what it is without a
   word of explanation — and they survive any depth, which a hand-written "in
   reply to X" line would not. */
.dsc-clist ol.children{padding-left:20px;margin:0 0 0 16px;border-left:2px solid var(--dsc-line)}
.dsc-clist ol.children>li{position:relative;margin:10px 0;padding:12px 14px;border-bottom:0;border-radius:var(--dsc-radius-sm);background:var(--dsc-bg-2)}
.dsc-clist ol.children>li::before{content:"";position:absolute;left:-20px;top:30px;width:12px;height:2px;background:var(--dsc-line)}
.dsc-clist ol.children .dsc-comment__avatar img{width:28px;height:28px}
@media (max-width:600px){
	.dsc-clist ol.children{padding-left:12px;margin-left:8px}
	.dsc-clist ol.children>li::before{left:-12px;width:8px}
}
.dsc-comments .comment-respond{margin-top:18px}
.dsc-comments label{display:block;font-size:.85rem;font-weight:600;margin-bottom:4px}
.dsc-comments input[type=text],.dsc-comments input[type=email],.dsc-comments input[type=url],.dsc-comments textarea{
	width:100%;border:1px solid var(--dsc-line);border-radius:var(--dsc-radius-sm);padding:11px 13px;font:inherit;background:var(--dsc-bg);color:var(--dsc-ink);margin-bottom:12px}
.dsc-comments textarea{border-radius:22px;padding:14px 18px}

/* The box and its toolbar read as one control: the border lives on the wrapper
   and the textarea inside gives its own up, or the strip looks like a row of
   buttons that happens to be sitting above an unrelated field. */
/* No overflow:hidden. It was here to keep the strip and the textarea inside the
   rounded border, and it did — along with the emoji panel, which opens out of
   the box by definition and was being clipped into invisibility. The corners are
   rounded on the two children instead, which is the same picture and does not
   cut anything off. */
.dsc-editor{display:block;border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);background:var(--dsc-bg);margin-bottom:12px}
.dsc-editor:focus-within{border-color:var(--dsc-ink-3)}
/* One emoji button and nothing else — see dsc_comment_toolbar(). */
.dsc-editor__bar{display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:6px 8px;border-bottom:1px solid var(--dsc-line);border-radius:var(--dsc-radius) var(--dsc-radius) 0 0;background:var(--dsc-bg-2)}
/* Downward here, unlike the chat. The strip sits at the top of the box, so a
   panel opening upward opens off the top of the comment form. */
/* Upward. The strip sits on top of the box, so a panel dropping out of it lands
   squarely over the field — the reader picked an emoji and could not see where
   it had gone, or what they had already written. Above the strip there is only
   the heading, and covering that costs nothing. */
.dsc-editor__bar .dsc-emoji__panel{bottom:calc(100% + 6px);top:auto}
.dsc-comments .dsc-editor textarea{border:0;border-radius:0 0 var(--dsc-radius) var(--dsc-radius);margin:0;padding:13px 16px;background:none}
.dsc-comments .dsc-editor textarea:focus{outline:0}

/* Anchored to the button rather than the page, and flipped above it: the form
   sits low enough that a panel opening downwards would hang off the screen. */
.dsc-emoji{position:relative;display:inline-flex;margin-left:auto}
.dsc-emoji__btn{display:inline-grid;place-items:center;min-width:32px;height:32px;border:0;border-radius:8px;background:none;font-size:1.05rem;line-height:1;cursor:pointer}
.dsc-emoji__btn:hover{background:var(--dsc-bg-3)}
.dsc-emoji__panel{position:absolute;right:0;bottom:calc(100% + 6px);z-index:20;display:grid;grid-template-columns:repeat(8,1fr);gap:2px;width:min(310px,calc(100vw - 40px));max-height:min(272px,42vh);overflow-y:auto;padding:8px;border:1px solid var(--dsc-line);border-radius:var(--dsc-radius-sm);background:var(--dsc-bg);box-shadow:var(--dsc-shadow)}
.dsc-emoji__opt{border:0;background:none;padding:4px 0;font-size:1.15rem;line-height:1.35;border-radius:6px;cursor:pointer}
.dsc-emoji__opt:hover{background:var(--dsc-bg-3)}
.dsc-comments .submit{background:var(--dsc-ink);color:var(--dsc-bg);border:0;border-radius:999px;padding:12px 26px;font-weight:800;cursor:pointer}

/* ==========================================================================
   7. Beeps (short news cards)
   ========================================================================== */
.dsc-beep{border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);overflow:hidden;background:var(--dsc-bg);display:flex;flex-direction:column}
.dsc-beep__media{display:block;aspect-ratio:16/9;background:var(--dsc-bg-3)}
.dsc-beep__media img{width:100%;height:100%;object-fit:cover}
.dsc-beep__body{padding:13px;display:flex;flex-direction:column;gap:7px;flex:1}
.dsc-beep__title{font-size:1rem;font-weight:800;margin:0;line-height:1.26;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.dsc-beep__txt{font-size:.9rem;color:var(--dsc-ink-2);margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.dsc-beep__more{margin-top:auto;font-size:.85rem;font-weight:700;text-decoration:none}

/* ==========================================================================
   7b. Media summary (YouTube-style) + ad slots
   ========================================================================== */
.dsc-msum{border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);background:var(--dsc-bg-2);margin:0 0 20px;overflow:hidden}
.dsc-msum__btn{display:flex;align-items:center;gap:9px;width:100%;background:none;border:0;padding:12px 14px;cursor:pointer;text-align:start;font-size:.94rem}
.dsc-msum__spark{color:#7b5cff;display:inline-flex;flex:none}
.dsc-msum__peek{flex:1;min-width:0;color:var(--dsc-ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dsc-msum__cta{font-weight:700;flex:none}
.dsc-msum__btn svg{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:2;transition:transform .2s}
.dsc-msum__btn[aria-expanded=true] svg{transform:rotate(180deg)}
.dsc-msum__btn[aria-expanded=true] .dsc-msum__peek{display:none}
.dsc-msum__body{padding:0 14px 14px}
.dsc-msum__body p{margin:0 0 8px;font-size:.95rem}
.dsc-msum__note{font-size:.76rem;color:var(--dsc-ink-3)}

.dsc-ad{display:block;margin:26px 0;text-align:center;overflow:hidden}
.dsc-ad__label{display:block;font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dsc-ink-3);margin-bottom:6px}
.dsc-ad iframe,.dsc-ad img{max-width:100%}
.dsc-grid>.dsc-ad{grid-column:1/-1}
/* The label belongs to a creative, not to the space one might arrive in. It
   stays hidden while the slot is still waiting to load ([data-dsc-ad]) and once
   the slot has given up ([data-empty]) — a lone "Advertisement" over several
   hundred pixels of nothing is the most visible bug an ad slot can have.

   Invisible while waiting, not removed: display:none gave the line back its
   height the moment the creative landed and pushed the article down by a label,
   every slot, every page. Gone entirely only once the slot has given up, where
   nothing is arriving to be pushed by. */
.dsc-ad[data-dsc-ad] .dsc-ad__label{visibility:hidden}
.dsc-ad[data-empty] .dsc-ad__label{display:none}
.dsc-ad[data-empty]{margin:0;min-height:0}
/* An empty slot that had a story parked in it is no longer empty space — it
   gets its spacing back, and never the "Advertisement" label, because what is
   on screen is not an ad. */
.dsc-ad[data-story]{margin:26px 0}
.dsc-adfill{text-align:start}

/* ==========================================================================
   7c. Motion cards (zooming still + player bar)
   ========================================================================== */
/* A card the reader has not reached costs nothing to lay out or paint. The
   stage carries an aspect-ratio, so the reserved height is right and nothing
   shifts when it does come into view. */
.dsc-mv{margin:30px 0;clear:both;content-visibility:auto;contain-intrinsic-size:auto 420px}
.dsc-mv__kicker{margin:0 0 8px;font-size:.72rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--dsc-ink-3)}
/* Edge to edge on a phone: inside the text column the unit reads as a banner,
   and a banner is the one thing every reader has trained themselves to skip. */
@media (max-width:699px){
	.dsc-mv{width:100vw;max-width:100vw;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw)}
	.dsc-mv__kicker{padding-inline:16px}
}
/* The height comes from the picture, not from a fixed frame the text then has
   to squeeze into. The active slide is in flow and sets the stage height; the
   others are stacked underneath it for the crossfade. The earlier version gave
   the photo whatever height the headline left over, which on a two-line
   headline was a slot, not a photograph. */
.dsc-mv__stage{position:relative;border-radius:var(--dsc-radius);overflow:hidden;background:var(--dsc-bg-2)}
/* After the base rule, not with the other phone overrides above it. Same
   specificity, so the one written last wins — and written first, the corners
   the full-bleed card is not supposed to have were rounding anyway, off both
   edges of the screen. */
@media (max-width:699px){.dsc-mv__stage{border-radius:0}}
/* pointer-events as well as visibility. The slides sit exactly on top of each
   other, and for the length of the crossfade the one going out is still a link
   under the finger — two overlapping targets, which is what a tap-target audit
   reports and what a tap during those 450ms could actually open. Nothing about
   the picture changes. */
.dsc-mv__slide{position:absolute;inset:0;display:flex;flex-direction:column;color:#fff;text-decoration:none;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .45s ease}
.dsc-mv__slide[data-active]{position:relative;opacity:1;visibility:visible;pointer-events:auto}
.dsc-mv__shot{position:relative;flex:none;width:100%;aspect-ratio:var(--dsc-mv-ratio,16/9);display:block;overflow:hidden}
/* One image per slide, cropped to the frame. The earlier build laid a blurred
   copy of the same photo underneath to avoid bars — two decoded images per
   slide plus a 26px blur, which is what took the phone score down. Match the
   frame to the photo library instead: the shape is a setting. */
.dsc-mv__pic{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover;transform-origin:52% 42%}
/* Camera moves rotate by slide — push left, push right, pull back, rise. One
   direction on every frame is an effect a reader can name, and an effect you
   can name has stopped working. Transforms only: the compositor animates these
   without repainting the picture. */
.dsc-mv__slide[data-active] .dsc-mv__pic{animation:dsc-mv-zoom var(--dsc-mv-dur,10s) linear both}
.dsc-mv__slide:nth-of-type(4n+2)[data-active] .dsc-mv__pic{animation-name:dsc-mv-zoom-b}
.dsc-mv__slide:nth-of-type(4n+3)[data-active] .dsc-mv__pic{animation-name:dsc-mv-zoom-c}
.dsc-mv__slide:nth-of-type(4n+4)[data-active] .dsc-mv__pic{animation-name:dsc-mv-zoom-d}
/* One light sweep across the frame, once per slide. Also transform-only. */
.dsc-mv__shot::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(104deg,transparent 34%,rgba(255,255,255,.24) 47%,rgba(255,255,255,.04) 55%,transparent 64%);transform:translateX(-130%)}
.dsc-mv__slide[data-active] .dsc-mv__shot::after{animation:dsc-mv-sweep 2.1s 1.1s ease-in-out both}
/* The fade is done at 78% and the rest of the box is empty. Run to the edge and
   the last band of it lands on 1/255 black, which Safari on a phone paints as a
   hairline right across the photo — and 38% of the frame is exactly where the
   player buttons sit, so it read as a line drawn through the controls. Nothing
   changes in the picture: the gradient was already invisible down there. */
.dsc-mv__veil{position:absolute;left:0;right:0;top:0;height:38%;background:linear-gradient(180deg,rgba(0,0,0,.38),rgba(0,0,0,0) 78%)}
.dsc-mv__meta{position:relative;z-index:2;flex:none;display:flex;flex-direction:column;align-items:flex-start;width:100%}
.dsc-mv__chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 -3px 16px;position:relative;z-index:1}
.dsc-mv__src{padding:5px 10px;background:#fff;color:#111418;font-size:.72rem;font-weight:800}
/* The headline sits on a plate under the picture, never over it, and it stays
   there for as long as the slide does — it does not fly in, hold and leave.
   Text that is only readable for part of a frame is text most readers never
   read at all, and a card whose words come and go reads as a fault. Text on a
   photograph is legible until the photograph is a white kitchen, and this unit
   picks its own pictures. min-height keeps every slide the same height, so the
   page does not jump when a two-line headline follows a one-line one. */
.dsc-mv__plate{width:100%;min-height:104px;padding:14px 16px 15px;background:var(--dsc-bg-2);color:var(--dsc-ink);display:flex;flex-direction:column;justify-content:center;gap:8px;overflow:hidden}
.dsc-mv__title{font-family:var(--dsc-font-body);font-size:clamp(1.1rem,4.2vw,1.34rem);font-weight:800;line-height:1.26;letter-spacing:-.01em;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.dsc-mv__cta{display:inline-flex;align-items:center;gap:5px;font-size:.84rem;font-weight:800;color:var(--dsc-accent)}
.dsc-mv__cta svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:2.4}
/* Transport on the picture, clear of the text — a player puts it there. */
.dsc-mv__bar{position:absolute;right:8px;top:calc(50% - 52px);z-index:2;display:flex;align-items:center;gap:2px}
.dsc-mv__btn{display:grid;place-items:center;flex:none;width:46px;height:46px;border:0;border-radius:50%;background:none;color:#fff;cursor:pointer;filter:drop-shadow(0 1px 5px rgba(0,0,0,.75))}
.dsc-mv__btn svg{width:25px;height:25px}
.dsc-mv__btn:hover{background:rgba(255,255,255,.2)}
.dsc-mv__ico{display:inline-flex;line-height:0}
.dsc-mv__ico--play{display:none}
.dsc-mv[data-held] .dsc-mv__ico--play{display:inline-flex}
.dsc-mv[data-held] .dsc-mv__ico--pause{display:none}
/* Segmented bars along the top: the Stories signal that this is a thing you
   swipe, readable before a word of the headline is. */
.dsc-mv__segs{position:absolute;top:0;left:0;right:0;z-index:3;display:flex;gap:5px;padding:11px 12px 0}
.dsc-mv__seg{flex:1;height:4px;background:rgba(255,255,255,.42);overflow:hidden}
.dsc-mv__fill{display:block;width:100%;height:100%;background:#fff;transform:scaleX(0);transform-origin:left}
.dsc-mv__fill[data-done]{transform:scaleX(1)}
.dsc-mv__fill[data-run]{animation:dsc-mv-fill var(--dsc-mv-dur,10s) linear forwards}
.dsc-mv__count{position:absolute;top:19px;inset-inline-end:12px;z-index:3;font-size:.72rem;font-weight:700;color:rgba(255,255,255,.9);font-variant-numeric:tabular-nums;text-shadow:0 1px 4px rgba(0,0,0,.7)}
/* Live count. Only rendered when the number is real — see dsc_social_proof(). */
.dsc-mv__live{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border-radius:5px;background:rgba(0,0,0,.62);color:#fff;font-size:.71rem;font-weight:700}
.dsc-mv__dot{width:6px;height:6px;border-radius:50%;background:#ff3b30;animation:dsc-mv-pulse 1.8s ease-in-out infinite}
@keyframes dsc-mv-pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.72)}}
/* Off screen, in a background tab, or paused by hand — one state, one rule.
   A unit the reader cannot see costs nothing. */
.dsc-mv[data-paused] .dsc-mv__fill,.dsc-mv[data-paused] .dsc-mv__pic,.dsc-mv[data-paused] .dsc-mv__shot::after{animation-play-state:paused}
@keyframes dsc-mv-zoom{from{transform:scale(1.02)}to{transform:scale(1.16) translate3d(-1.2%,-1.4%,0)}}
@keyframes dsc-mv-zoom-b{from{transform:scale(1.02)}to{transform:scale(1.16) translate3d(1.4%,-1%,0)}}
@keyframes dsc-mv-zoom-c{from{transform:scale(1.17)}to{transform:scale(1.02) translate3d(0,.6%,0)}}
@keyframes dsc-mv-zoom-d{from{transform:scale(1.04) translate3d(0,1.4%,0)}to{transform:scale(1.18)}}
@keyframes dsc-mv-fill{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes dsc-mv-sweep{from{transform:translateX(-130%)}to{transform:translateX(130%)}}
@media (min-width:700px){.dsc-mv__plate{min-height:112px;padding:16px 20px 17px}.dsc-mv__bar{right:14px}}

/* --- Second look, kept as a choice: the headline over the photograph instead
   of under it, and the transport back in a bar along the bottom. Same markup,
   same script — everything below is presentation, so neither look can rot. */
.dsc-mv[data-style=overlay] .dsc-mv__stage{aspect-ratio:var(--dsc-mv-ratio,16/9)}
.dsc-mv[data-style=overlay] .dsc-mv__slide,.dsc-mv[data-style=overlay] .dsc-mv__slide[data-active]{position:absolute;display:block}
.dsc-mv[data-style=overlay] .dsc-mv__shot{position:absolute;inset:0;aspect-ratio:auto}
.dsc-mv[data-style=overlay] .dsc-mv__veil{height:100%;background:linear-gradient(180deg,rgba(0,0,0,.3) 0%,rgba(0,0,0,0) 26%,rgba(0,0,0,.72) 74%,rgba(0,0,0,.9) 100%)}
.dsc-mv[data-style=overlay] .dsc-mv__meta{position:absolute;left:0;right:0;bottom:58px;width:auto;padding:0 14px;gap:9px}
.dsc-mv[data-style=overlay] .dsc-mv__chips{margin:0}
.dsc-mv[data-style=overlay] .dsc-mv__plate{width:auto;min-height:0;padding:0;background:none;color:#fff;gap:10px;align-items:flex-start}
.dsc-mv[data-style=overlay] .dsc-mv__title{font-family:var(--dsc-font-head);-webkit-line-clamp:3;text-shadow:0 1px 14px rgba(0,0,0,.6)}
.dsc-mv[data-style=overlay] .dsc-mv__cta{padding:9px 18px;border-radius:999px;background:var(--dsc-accent);color:var(--dsc-accent-ink)}
.dsc-mv[data-style=overlay] .dsc-mv__bar{top:auto;right:0;left:0;bottom:0;justify-content:flex-start;gap:2px;padding:8px 8px 10px;background:linear-gradient(180deg,rgba(0,0,0,0),rgba(0,0,0,.55))}
.dsc-mv[data-style=overlay] .dsc-mv__btn{width:40px;height:40px}
.dsc-mv[data-style=overlay] .dsc-mv__btn svg{width:21px;height:21px}
@media (prefers-reduced-motion:reduce){
	.dsc-mv__slide{transition:none}
	.dsc-mv__pic,.dsc-mv__shot::after,.dsc-mv__fill,.dsc-mv__dot{animation:none!important}
	.dsc-mv__fill{transform:scaleX(1)}
}

/* ==========================================================================
   7d. Feedback card
   ========================================================================== */
.dsc-fb{position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom));z-index:60;width:min(440px,calc(100vw - 24px));transform:translate(-50%,16px);opacity:0;pointer-events:none;transition:opacity .25s ease,transform .25s ease,translate .22s ease}
.dsc-fb[data-open]{opacity:1;transform:translate(-50%,0);pointer-events:auto}
/* Same travel as the chat disc — see the note there for why it is a translate. */
@media (max-width:899px){
	body:has([data-dsc-stickybar]) .dsc-fb{bottom:calc(66px + env(safe-area-inset-bottom));translate:0 52px}
	body:has([data-dsc-stickybar][data-visible]) .dsc-fb{translate:none}
}
.dsc-fb__card{position:relative;padding:16px 18px 12px;border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);background:var(--dsc-bg);box-shadow:var(--dsc-shadow);text-align:center}
.dsc-fb__x{position:absolute;top:6px;inset-inline-end:6px}
.dsc-fb__q{margin:0 0 12px;font-size:1.02rem;font-weight:800}
.dsc-fb__row{display:flex;gap:10px;justify-content:center}
.dsc-fb__row .dsc-btn{min-width:104px}
.dsc-fb__done{margin:0;font-size:.95rem;color:var(--dsc-ink-2)}
.dsc-fb__off{display:block;margin:12px auto 0;padding:4px;border:0;background:none;font-size:.74rem;color:var(--dsc-ink-3);text-decoration:underline;cursor:pointer}
@media (prefers-reduced-motion:reduce){.dsc-fb{transition:none}}

/* ==========================================================================
   8. Footer / misc
   ========================================================================== */
.dsc-btn{border:0;border-radius:999px;padding:11px 20px;font-weight:700;cursor:pointer;background:var(--dsc-accent);color:var(--dsc-accent-ink)}
.dsc-btn--ghost{background:var(--dsc-bg-2);color:var(--dsc-ink)}

/* The tall bottom padding exists to clear the sticky share bar. Pages without
   one (the homepage, archives) get the normal spacing. */
.dsc-footer{border-top:1px solid var(--dsc-line);margin-top:44px;padding:28px 0 calc(34px + env(safe-area-inset-bottom));background:var(--dsc-bg-2);color:var(--dsc-ink-2);font-size:.9rem}
body:has([data-dsc-stickybar]) .dsc-footer{padding-bottom:calc(92px + env(safe-area-inset-bottom))}
.dsc-footer__social{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-bottom:18px}
.dsc-footer__social a{display:grid;place-items:center;width:52px;height:40px;border:1.5px solid var(--dsc-line);border-radius:10px;background:var(--dsc-bg)}
.dsc-footer__social svg{width:22px;height:22px}
.dsc-footer nav ul{list-style:none;display:flex;gap:16px;justify-content:center;flex-wrap:wrap;padding:0;margin:0 0 14px}
.dsc-footer a{color:var(--dsc-ink-2)}
/* A <button> that has to read as a footer link. Unstyled it kept the browser's
   own grey box and sat off to one side of an otherwise centred footer, which
   reads as something broken rather than something optional. */
.dsc-footer__optout{text-align:center;margin:0 0 12px}
.dsc-linkbtn{border:0;background:none;padding:0;font:inherit;font-size:.82rem;color:var(--dsc-ink-3);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.dsc-linkbtn:hover{color:var(--dsc-ink)}
.dsc-footer__copy{text-align:center;font-size:.82rem;color:var(--dsc-ink-3)}
@media (min-width:900px){.dsc-footer,body:has([data-dsc-stickybar]) .dsc-footer{padding-bottom:34px}}

/* The row is the <nav> itself (custom markup) or the .nav-links wrapper that
   core's the_posts_pagination adds — never the links themselves, which are
   inline chips. */
.dsc-pagination{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:30px 0}
.dsc-pagination .nav-links{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;width:100%}
.dsc-pagination .page-numbers{display:inline-grid;place-items:center;min-width:40px;height:40px;padding:0 12px;border:1px solid var(--dsc-line);border-radius:10px;text-decoration:none;color:var(--dsc-ink)}
.dsc-pagination .screen-reader-text{display:none}
.dsc-pagination--pages{justify-content:flex-start;gap:6px;margin:18px 0}
.dsc-pagination--pages .page-numbers-label{align-self:center;font-weight:700;color:var(--dsc-ink-3)}
.dsc-pagination .current{background:var(--dsc-ink);color:var(--dsc-bg);border-color:var(--dsc-ink)}

.dsc-empty{text-align:center;padding:50px 0}
/* One line, never a paragraph: the post title is the last crumb and long titles
   used to wrap the trail onto two or three rows above the headline. */
.dsc-breadcrumbs{font-size:.8rem;color:var(--dsc-ink-3);margin:10px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dsc-breadcrumbs a{color:var(--dsc-ink-3);text-decoration:none}
.dsc-breadcrumbs a:hover{color:var(--dsc-accent)}

/* WP core classes */
.alignwide{max-width:min(100%,980px);margin-inline:auto}
.alignfull{width:100vw;max-width:100vw;margin-left:calc(50% - 50vw)}
.alignleft{float:left;margin:.3em 1.2em .8em 0}
.alignright{float:right;margin:.3em 0 .8em 1.2em}
.aligncenter{margin-inline:auto}
.wp-caption-text,.wp-element-caption{font-size:.79rem;color:var(--dsc-ink-3)}
.sticky .dsc-card__title::before{content:"★ ";color:var(--dsc-accent)}
.gallery{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.gallery-item img{border-radius:var(--dsc-radius-sm)}

/* ==========================================================================
   9. Chat
   ========================================================================== */
/* Fixed, so it never participates in layout and never shifts anything. Hidden
   until the script has something to put in it — an empty pill that says nothing
   is worse than no pill. z-index sits above the sticky share bar (45) and below
   the feedback panel (60). */
/* Anchored to the corner on every screen size. It used to be a full-width bar
   lying across the article, which is why it had to hide itself on every scroll
   — and a control that keeps vanishing and reappearing is worse than one that
   covers a little. A disc in the corner covers a corner, so it can simply
   stay. */
/* column-reverse, not block flow: the panel is printed after the sticker so a
   script-less page still has the sticker first in the tab order, but it has to
   sit above it on screen. Without this the room hangs off the bottom edge.
   The width is stated rather than shrink-to-fit — a fixed box with left:auto
   sizes itself to its own min-content, and one long word in a message was
   enough to push it past the right edge of a phone. */
.dsc-chat{position:fixed;z-index:55;left:auto;right:14px;bottom:calc(14px + env(safe-area-inset-bottom));width:min(360px,calc(100vw - 28px));display:flex;flex-direction:column-reverse;align-items:flex-end;pointer-events:none;transition:translate .22s ease,opacity .2s ease,visibility .2s}
.dsc-chat>*{pointer-events:auto}
/* Nothing until the reader has finished an article — see inc/chat.php. The
   script takes this off, and takes it off for good once it has: reading on
   through the infinite feed never puts it back, only the cross does. */
.dsc-chat.is-waiting{display:none}
/* Out of the way of the comment form — see initChatHush(). Not display:none:
   the disc has to be able to fade back in where it stood, and a display swap
   would re-run the arrive animation as if it had only just earned its place. */
.dsc-chat.is-hushed{opacity:0;visibility:hidden}
/* Arrives from the edge rather than blinking into existence. Something that
   appears mid-scroll with no movement reads as a rendering glitch. */
.dsc-chat:not(.is-waiting){animation:dsc-chat-arrive .4s ease both}
@keyframes dsc-chat-arrive{from{transform:translateX(46px);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){.dsc-chat:not(.is-waiting){animation:none}}
/* Mobile only: the share bar owns the very bottom of the screen on articles —
   but only while it is actually out. Keyed on the bar merely existing, the disc
   sat 78px up on every article whether the bar was on screen or not, which is
   what made it look like it was hanging in mid-air.
   The travel is a translate, never an animated bottom. bottom is a layout
   property: transitioning it on a fixed element makes iOS re-lay-out and
   repaint the thing on every frame of every scroll direction change, which is
   the stutter that looked like the disc was hopping. translate rides on the
   compositor, on the same .22s the bar itself uses, so the two move as one. */
@media (max-width:899px){
	body:has([data-dsc-stickybar]) .dsc-chat{bottom:calc(66px + env(safe-area-inset-bottom));translate:0 52px}
	body:has([data-dsc-stickybar][data-visible]) .dsc-chat{translate:none}
}

/* A disc, and nothing else. It used to grow into a pill carrying the last thing
   said, which meant a third state between "closed" and "open" — one that moved
   on its own every time somebody wrote, covered a strip of the article while it
   was out, and put a second cross on screen that did not do what the first one
   did. Two states are the whole design: a disc in the corner, and the room.
   What the pill was for — somebody is talking — is the count on the rim. */
.dsc-chat__bar{position:relative;display:grid;place-items:center;width:58px;height:58px;padding:0;border:1px solid var(--dsc-line);border-radius:50%;box-shadow:var(--dsc-shadow);transition:box-shadow .2s ease;background:color-mix(in srgb,var(--dsc-accent) 8%,var(--dsc-bg));border-color:color-mix(in srgb,var(--dsc-accent) 32%,var(--dsc-line))}
@media (hover:hover){.dsc-chat__bar:hover{box-shadow:0 2px 4px rgba(16,24,40,.08),0 14px 28px -14px rgba(16,24,40,.3)}}
/* The disc has nothing to say while the room is on screen. Keyed on the panel
   still being in the document rather than on .is-open, because .is-open comes
   off at the start of the closing fade and the disc would pop back under a
   sheet that is still visible. */
.dsc-chat:has(.dsc-chat__room:not([hidden])) .dsc-chat__bar{display:none}

/* The grey flash on tap is the system's, not ours — and on a round button it
   arrives as a square, which is what made a plain press look like a glitch. */
.dsc-chat__open,.dsc-chat__collapse,.dsc-chat__tab,.dsc-chat__like,.dsc-chat__replybtn,.dsc-chat__me,.dsc-chat__send{-webkit-tap-highlight-color:transparent}
.dsc-chat__open{display:grid;place-items:center;width:100%;height:100%;border:0;border-radius:50%;background:none;padding:0;font:inherit;color:var(--dsc-ink);cursor:pointer}
.dsc-chat__emoji{display:block;font-size:1.45rem;line-height:1;animation:dsc-chat-wave 5s ease-in-out infinite}
.dsc-chat__collapse svg{display:block}

/* On the rim of the disc, hanging off it — a count sitting inside the circle
   reads as part of the icon. Positioned against .dsc-chat rather than the bar,
   because the bar clips its own overflow to collapse the pill and would cut
   this in half. The ring in the site's background colour keeps it legible
   whatever it happens to be overlapping. */
.dsc-chat__count{position:absolute;right:-4px;bottom:40px;z-index:2;display:none;place-items:center;min-width:21px;height:21px;padding:0 6px;border-radius:999px;background:#e5484d;color:#fff;font-size:.7rem;font-weight:800;line-height:1;box-shadow:0 0 0 2px var(--dsc-bg);pointer-events:none}
/* The panel carries the messages themselves; a count of unread ones on top of
   it is a number about something the reader is already looking at. */
.dsc-chat:has(.dsc-chat__room:not([hidden])) .dsc-chat__count{display:none}
.dsc-chat.is-unread .dsc-chat__count{display:grid;animation:dsc-chat-badge 1.8s ease-in-out infinite}
@keyframes dsc-chat-badge{0%,72%,100%{transform:scale(1)}80%{transform:scale(1.2)}88%{transform:scale(.96)}}

/* Am I actually connected? Green while the polls come back, red once one has
   not — see setLive(). The ring is what keeps a 7px dot visible against a
   header that changes colour with the scheme. */
.dsc-chat__live{flex:none;display:inline-grid;place-items:center;width:14px;height:14px}
.dsc-chat__dot{width:7px;height:7px;border-radius:50%;background:#2ea043;box-shadow:0 0 0 2px color-mix(in srgb,#2ea043 22%,transparent)}
.dsc-chat.is-offline .dsc-chat__dot{background:#e5484d;box-shadow:0 0 0 2px color-mix(in srgb,#e5484d 22%,transparent);animation:dsc-chat-blink 1.4s ease-in-out infinite}
@keyframes dsc-chat-blink{0%,100%{opacity:1}50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){.dsc-chat.is-offline .dsc-chat__dot{animation:none}}
/* The count reads as part of the dot, not as a third thing in the row: pulled
   back over the header's 8px gap so the two sit as one "someone is here" mark.
   Digits only — the sentence is in the screen-reader span beside it. */
.dsc-chat__crowd{flex:none;margin-left:-4px;font-size:.72rem;font-weight:700;color:var(--dsc-ink-3);font-variant-numeric:tabular-nums}

/* The icon shakes itself awake every few seconds. Long gap, short shake: a
   permanent animation in the corner of the screen stops being noticed within a
   minute and starts being irritating a minute later. */
/* A pulse, not a tilt. The rotation read as a badly aligned icon far more often
   than as a wave — an emoji is not symmetrical, so any angle on it looks like a
   mistake rather than a motion. */
@keyframes dsc-chat-wave{
	0%,86%,100%{transform:scale(1)}
	89%{transform:scale(1.16)}
	93%{transform:scale(.96)}
	96%{transform:scale(1.04)}
}
@media (prefers-reduced-motion:reduce){
	.dsc-chat__emoji,.dsc-chat.is-unread .dsc-chat__count{animation:none}
	.dsc-chat,.dsc-chat__bar{transition:none}
}

/* svh, not dvh: the small viewport is the one that does not change when a
   mobile browser hides its address bar, so the panel keeps its height instead
   of resizing under the reader on every scroll. */
.dsc-chat__room{display:flex;flex-direction:column;width:100%;height:min(62vh,460px);max-height:calc(100svh - 150px);margin-bottom:8px;background:var(--dsc-bg);border:1px solid var(--dsc-line);border-radius:var(--dsc-radius);box-shadow:var(--dsc-shadow);overflow:hidden;opacity:0;transform:translateY(12px);transition:opacity .2s ease,transform .2s ease}
.dsc-chat.is-open .dsc-chat__room{opacity:1;transform:none}

/* On a phone the room is a sheet over the site, not a card in a corner. A
   360px panel on a 393px screen is a card with nowhere to sit: it covers the
   article it is floating over anyway, and half of it is spent on the gap. Full
   width, full height, one thing on screen — and the cross puts it back. */
@media (max-width:640px){
	/* Height and top come from the visual viewport, not from the layout one.
	   iOS does not shrink the page when the keyboard opens — it slides the
	   visible area down over an unchanged layout — so a sheet told to be 100%
	   tall stays full-page-tall and ends up half off screen with its own input
	   underneath the keys. The script feeds it the two numbers; the fallbacks
	   are what every other browser needs anyway. */
	/* Geometry hangs off the panel being in the document, not off .is-open.
	   .is-open is the animation state and comes off the moment the cross is
	   pressed, 220ms before the panel is hidden — keyed on it, the sheet
	   snapped back to a corner card above the disc for those 220ms while it
	   was still fading out, which is the jump the reader saw on close. */
	.dsc-chat:has(.dsc-chat__room:not([hidden])){left:var(--dsc-chat-left,0px);right:auto;bottom:auto;top:var(--dsc-chat-top,0px);width:var(--dsc-chat-vw,100%);height:var(--dsc-chat-vh,100dvh);z-index:70;translate:none}
	/* The slide-up is the shut state, not the open one. Written on .is-open it
	   stuck: the sheet came to rest three per cent down the screen, which on a
	   phone is the strip of header still showing above it, and the animation it
	   was meant to be never played at all. */
	.dsc-chat__room{transform:translateY(3%)}
	/* The keyboard is padding, not a smaller sheet — see fitSheet(). Whichever
	   is taller, the home-indicator inset or the keys currently covering the
	   bottom of the screen. */
	.dsc-chat:has(.dsc-chat__room:not([hidden])) .dsc-chat__room{height:100%;max-height:none;margin:0;border:0;border-radius:0;padding-bottom:max(env(safe-area-inset-bottom),var(--dsc-chat-kb,0px))}
	.dsc-chat:has(.dsc-chat__room:not([hidden])) .dsc-chat__head{padding-top:calc(8px + env(safe-area-inset-top))}
	/* The article carries on scrolling behind a full-screen sheet otherwise, so
	   closing the chat drops the reader somewhere they never scrolled to. */
	body:has(.dsc-chat__room:not([hidden])){overflow:hidden}
}
@media (prefers-reduced-motion:reduce){.dsc-chat__room{transition:none}}
.dsc-chat__head{display:flex;align-items:center;gap:8px;padding:8px 8px 8px 10px;border-bottom:1px solid var(--dsc-line)}
/* No scrollbar. There are two rooms — this article's category and the general
   one — and a horizontal scroller appeared only because one category name was
   long enough to push the other tab out. Letting the long one shrink and
   ellipsise is what a reader expects; a scrollbar inside a 58px-tall header is
   a thing nobody finds. */
.dsc-chat__tabs{flex:1;display:flex;gap:6px;min-width:0;overflow:hidden}
.dsc-chat__tab{flex:0 1 auto;min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:1px solid var(--dsc-line);border-radius:999px;background:var(--dsc-bg-2);color:var(--dsc-ink-2);font:inherit;font-size:.76rem;font-weight:700;padding:4px 11px;cursor:pointer}
.dsc-chat__tab[aria-selected=true]{background:var(--dsc-accent);border-color:var(--dsc-accent);color:var(--dsc-accent-ink)}
/* Both tabs shrank at the same rate, so a long category name left the reader
   looking at "Ylein…" — the room they are actually in, unreadable, to make
   space for the one they are not. The selected tab holds its width and the
   other one ellipsises; the cap stops a long selected name from doing the same
   thing in reverse. Only with two of them: a lone tab has the row to itself. */
.dsc-chat__tabs:has(.dsc-chat__tab+.dsc-chat__tab) .dsc-chat__tab[aria-selected=true]{flex-shrink:0;max-width:62%}
/* place-items, like its twin on the bar. Without it the drawn cross sits in the
   top-left of the circle instead of the middle — a button with an icon in it
   still has to say where the icon goes. Bigger on a phone: a 28px target is
   under every hit-area guideline there is, and this one closes the chat. */
.dsc-chat__collapse{flex:none;display:grid;place-items:center;width:32px;height:32px;border:0;border-radius:50%;background:var(--dsc-bg-2);color:var(--dsc-ink-3);cursor:pointer}
@media (max-width:640px){.dsc-chat__collapse{width:40px;height:40px}}

/* Two sizes, one button. On a phone the room is already the whole screen, so
   the button is not there at all rather than there and useless. */
.dsc-chat__wide{display:none}
@media (min-width:641px){
	.dsc-chat__wide{flex:none;display:grid;place-items:center;width:32px;height:32px;border:0;border-radius:50%;background:var(--dsc-bg-2);color:var(--dsc-ink-3);cursor:pointer}
	.dsc-chat__wide svg{display:block}
	.dsc-chat__wide svg:last-child,.dsc-chat.is-wide .dsc-chat__wide svg:first-child{display:none}
	.dsc-chat.is-wide .dsc-chat__wide svg:last-child{display:block}
	/* The width lives on the outer element — it is what the panel is measured
	   against — and the height on the room itself. Both stay inside the viewport
	   on a small laptop, which is why neither is a flat number. */
	.dsc-chat.is-wide{width:min(920px,calc(100vw - 28px))}
	.dsc-chat.is-wide .dsc-chat__room{height:min(70vh,620px);max-height:calc(100svh - 110px)}
}

.dsc-chat__log{flex:1;overflow-y:auto;overscroll-behavior:contain;list-style:none;margin:0;padding:12px;display:flex;flex-direction:column;gap:16px;font-size:.86rem}
.dsc-chat__msg{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:start}
.dsc-chat__avatar{font-size:1.05rem;line-height:1.3}
.dsc-chat__who{display:block;margin-bottom:3px;font-size:.72rem;font-weight:700;color:var(--dsc-ink-3)}
/* Block, not the inline span it used to be: inline put the thumb and the reply
   arrow on the same line as the last word of the message, hard against it. */
.dsc-chat__text{display:block;line-height:1.45;overflow-wrap:anywhere}
/* Kept quiet by colour, not by opacity. Fading the whole strip to a third took
   the thumb somebody had already pressed down with it, so their own like came
   back looking greyed out and switched off — which is the one state it must
   never look like. A muted background says "secondary" perfectly well. */
.dsc-chat__tools{display:inline-flex;gap:6px;margin-top:7px}
.dsc-chat__like,.dsc-chat__replybtn,.dsc-chat__hide{border:0;border-radius:999px;background:var(--dsc-bg-2);color:var(--dsc-ink-2);font:inherit;font-size:.72rem;font-weight:700;line-height:1;padding:6px 10px;cursor:pointer}
/* Clearing your own line, and clearing all of them. Both only ever change what
   this reader sees — see hiddenSet() — so neither is styled as a destructive
   action. A red button here would promise something it does not do. */
.dsc-chat__hide{font-size:.95rem;padding:3px 10px 5px}
.dsc-chat__hide:hover{color:#e5484d}
.dsc-chat__wipe{flex:none;display:grid;place-items:center;width:32px;height:32px;border:0;border-radius:50%;background:var(--dsc-bg-2);font-size:.85rem;line-height:1;cursor:pointer}
/* Asked, waiting for the second tap. The armed state is the only red in the
   header, which is the whole point of it. */
.dsc-chat__wipe.is-armed{background:color-mix(in srgb,#e5484d 18%,var(--dsc-bg-2));box-shadow:0 0 0 2px color-mix(in srgb,#e5484d 34%,transparent)}
@media (max-width:640px){.dsc-chat__wipe{width:40px;height:40px}}
.dsc-chat__like:hover,.dsc-chat__replybtn:hover{background:var(--dsc-bg-3)}
.dsc-chat__like.is-mine{opacity:1;background:var(--dsc-accent);color:var(--dsc-accent-ink)}
.dsc-chat__msg--mine .dsc-chat__who{color:var(--dsc-accent)}
/* Somebody answered you. A tint the width of the line, not a marker in the
   margin — the reader is scrolling a wall of grey text and the thing that has
   to catch the eye is the message itself. */
.dsc-chat__msg--tome{padding:7px 9px;margin:0 -9px;border-radius:12px;background:color-mix(in srgb,var(--dsc-accent) 11%,transparent)}
.dsc-chat__msg--desk .dsc-chat__text{font-weight:700}
.dsc-chat__empty{color:var(--dsc-ink-3);text-align:center;margin:auto 0;padding:20px 10px}

/* flex-end, not center: the box grows upward as the text wraps and the buttons
   have to stay on the line the reader is typing on. Positioned, because the
   emoji panel hangs off the form rather than off the little button that opens
   it — see below. */
.dsc-chat__form{position:relative;display:flex;align-items:flex-end;gap:6px;padding:8px;border-top:1px solid var(--dsc-line)}
.dsc-chat__me{flex:none;width:34px;height:34px;border:1px solid var(--dsc-line);border-radius:50%;background:var(--dsc-bg-2);font-size:1.05rem;line-height:1;cursor:pointer}
/* Pressed, because the line below it is now the name and not the message. The
   badge itself stays put — moving it would leave nothing saying what changed. */
.dsc-chat.is-renaming .dsc-chat__me{background:var(--dsc-accent);border-color:var(--dsc-accent)}
.dsc-chat.is-renaming .dsc-chat__input{border-color:var(--dsc-accent)}
/* One row tall until the text needs a second one, then up to four. resize:none
   because the drag handle a textarea comes with would let the reader pull the
   box over the conversation they are answering. */
.dsc-chat__input{flex:1;min-width:0;border:1px solid var(--dsc-line);border-radius:18px;background:var(--dsc-bg-2);color:var(--dsc-ink);font:inherit;font-size:.88rem;line-height:1.4;padding:8px 13px;resize:none;overflow-y:hidden;max-height:96px}
/* 16px exactly, and below the rule it overrides — a media query adds no
   specificity, so the same selector further down the file wins whatever the
   screen size. Under 16px Safari zooms the whole page in the moment the field
   takes focus and never zooms back out, which is what was cutting the sheet
   off at the right edge: a fixed element is laid out in the layout viewport,
   and zooming makes that wider than the screen. */
@media (max-width:640px){.dsc-chat__input{font-size:16px}}
/* The picker opens upward, over the log. The room clips its own overflow, which
   is what keeps the panel inside the chat instead of hanging off the page. */
/* static, so the panel below measures itself against the form. Anchored to the
   button it opens from, a 280px panel hanging off a control that sits 240px
   from the left edge of a 360px room starts 34px outside it — and the room
   clips its own overflow, so that is 34px of emoji sliced off. Against the
   form it can only ever be as wide as the room it lives in. */
.dsc-chat__form .dsc-emoji{position:static;margin-left:0}
.dsc-chat__form .dsc-emoji__btn{width:34px;height:34px;border-radius:50%;background:var(--dsc-bg-2)}
.dsc-chat__form .dsc-emoji__btn:hover{background:var(--dsc-bg-3)}
/* Edge to edge of the form. 180px tall showed four and a half rows and cut the
   fifth in half, which reads as a broken panel rather than a scrollable one. */
.dsc-chat__form .dsc-emoji__panel{left:8px;right:8px;width:auto;max-height:min(272px,42vh)}
.dsc-chat__send{flex:none;border:0;border-radius:999px;background:var(--dsc-accent);color:var(--dsc-accent-ink);font:inherit;font-size:.82rem;font-weight:700;padding:9px 14px;cursor:pointer}
.dsc-chat__send[disabled]{opacity:.5;cursor:default}
/* Lined up with the message field, not with the edge of the form. The countdown
   is about that field, and two pixels out of true reads as a mistake. 48px is
   the avatar button plus the gap in front of it. */
.dsc-chat__note{margin:0;padding:0 12px 8px 48px;font-size:.76rem;color:var(--dsc-ink-3);min-height:1.2em}
.dsc-chat__note[data-error]{color:#b3261e}
