/* Dental Pro — add-on token bridge, add-on skins, and the tile components the
 * Directorist taxonomy screens need.
 *
 * This file is NOT design CSS and it introduces no colour value of its own: the
 * first part feeds the design's own tokens into the custom properties the two
 * Directorist add-ons already read, so their widgets follow the palette (and the
 * light/dark switch) instead of painting their own. After that come three
 * sections that the token layer cannot reach: the handful of places each add-on
 * hard-codes a colour the tokens then contradict, the symptom widget's component
 * skin, and -- at the end of the file, and flagged there for deletion -- a
 * verbatim copy of front-page.css's `.spec*` / `.city*` tiles, which the
 * taxonomy screens render but front-page.css is not enqueued for.
 *
 * Both add-ons were built to be re-themed this way, so nothing here reaches past
 * their token layer:
 *
 *   Advanced Booking — src/shared/tokens.css declares every --dab-* role on
 *   `.dab-w, .dab-d, .dab-b, .dab-admin`, each one resolving through a
 *   --directorist-* property with a hardcoded fallback (its primary falls back
 *   to #2563eb, the blue). Overriding the six source roles is enough: the
 *   plugin derives --dab-color-line, --dab-color-subtle, --dab-color-tint and
 *   --dab-color-tint-strong from them with color-mix(), so those follow on
 *   their own and keep the contrast floors the plugin documents. Spacing, type
 *   scale and radius are left alone — they are not palette, and --dab-radius
 *   already resolves to 10px, which matches the design's 11px control radius
 *   far better than --r (28px, the card radius) would.
 *
 *   Smart Assistant — assets/build/symptom-search.css declares every --ss-*
 *   role on `.dsa-ss` as var(--dc-<role>, <teal fallback>). The --dc-* layer is
 *   the documented host hook, so that is what gets set here rather than any
 *   --ss-* internal.
 *
 * Specificity: both plugins declare their tokens at one class
 * (`.dab-w{…}`, `.dsa-ss{…}`). The `body` prefix here lifts these to (0,0,1,1)
 * so the mapping wins whatever order the stylesheets happen to print in, while
 * still losing to the inline style Advanced Booking writes on the widget root
 * when a site owner has set a colour in its admin — an explicit choice there
 * should still beat the theme.
 *
 * Tokens used: --acc, --card, --cardS, --field, --fg, --line, --mute, --sky,
 * --shadow, --r, --urg. All defined in assets/css/theme.css for both colour
 * modes, so every value below switches with the theme.
 */

/* ---------------------------------------------------------------------------
 * Directorist core -- the plugin's own palette.
 *
 * Directorist prints its colour settings as `:root { --directorist-color-* }`
 * in an inline style (specificity 0,0,0) and reads them from every screen the
 * theme does not override outright: sign-in and registration, the dashboard,
 * add-listing, the contact-owner form, the report modal, pagination and the
 * notices. The site's saved primary is a slate grey (#444752), which is not a
 * design colour. Re-pointing the roles at the design's tokens on `body`
 * (0,0,1) beats the plugin's `:root` in either print order and switches with
 * the light/dark mode, so the plugin's untouched screens read as part of the
 * site instead of as a different product.
 *
 * `--directorist-color-primary-rgb` is the one role the plugin composes with
 * alpha (`rgba(var(--directorist-color-primary-rgb), .8)` on hover), and a
 * custom property cannot be decomposed into channels, so the design's two
 * accent values are spelled out per mode, mirroring theme.css: dark is the
 * `:root` default, light is `[data-theme="light"]` or the light scheme with no
 * explicit choice.
 * ------------------------------------------------------------------------ */

body {
	--directorist-color-primary: var(--acc);
	--directorist-color-primary-rgb: 95, 227, 184;
	--directorist-color-secondary: var(--cardS);
	--directorist-color-dark: var(--fg);
	--directorist-color-body: var(--fg);
	--directorist-color-white: var(--card);
	--directorist-color-gray: var(--mute);
	--directorist-color-gray-hover: var(--fg);
	--directorist-color-light: var(--cardS);
	--directorist-color-light-hover: var(--acc2);
	--directorist-color-light-gray: var(--mute);
	--directorist-color-deep-gray: var(--mute);
	--directorist-color-bg-gray: var(--bg2);
	--directorist-color-bg-light-gray: var(--bg2);
	--directorist-color-bg-light: var(--cardS);
	--directorist-color-placeholder: var(--mute);
	--directorist-color-border: var(--line);
	--directorist-color-border-light: var(--line);
	--directorist-color-border-gray: var(--line);
	--directorist-color-danger: var(--urg);
	--directorist-color-star: var(--star);
	--directorist-color-marker-shape: var(--acc);
	--directorist-color-marker-icon: var(--accfg);
	--directorist-box-shadow: var(--shadow);
	--directorist-box-shadow-sm: none;
	--directorist-border-radius-xs: 10px;
	--directorist-border-radius-sm: 12px;
	--directorist-border-radius-md: 14px;
	--directorist-border-radius-lg: 18px;
	--directorist-color-btn: var(--acc);
	--directorist-color-btn-hover: var(--acc);
	--directorist-color-btn-border: var(--acc);
	--directorist-color-btn-primary: var(--accfg);
	--directorist-color-btn-primary-bg: var(--acc);
	--directorist-color-btn-primary-border: var(--acc);
	--directorist-color-btn-secondary: var(--fg);
	--directorist-color-btn-secondary-bg: var(--cardS);
	--directorist-color-btn-secondary-border: var(--line);
}

:root[data-theme="light"] body {
	--directorist-color-primary-rgb: 6, 122, 88;
}

@media (prefers-color-scheme: light) {

	:root:not([data-theme="dark"]) body {
		--directorist-color-primary-rgb: 6, 122, 88;
	}
}

/* The plugin pairs its primary fill with `--directorist-color-white` for the
   label. That token is now the card surface, which is near-transparent on the
   dark palette; filled buttons take the design's own pairing instead. */
body .directorist-btn,
body .directorist-btn-primary,
body .directorist-btn-submit,
body .directorist-btn-search {
	color: var(--accfg);
}

body .directorist-btn-light,
body .directorist-btn-secondary {
	color: var(--fg);
	background-color: var(--cardS);
	border-color: var(--line);
}

body .directorist-btn-light:hover,
body .directorist-btn-secondary:hover {
	color: var(--acc);
	background-color: var(--acc2);
	border-color: var(--acc);
}

/* ---------------------------------------------------------------------------
 * Directorist Advanced Booking — the booking widget, dashboard and builder.
 * ------------------------------------------------------------------------ */

body .dab-w,
body .dab-d,
body .dab-b {

	/* Selection, focus rings and filled controls. */
	--dab-color-primary: var(--acc);

	/* Panels: service rows, the calendar, the timezone select. */
	--dab-color-surface: var(--card);

	/* Decorative edges. --dab-color-line, the 3:1 affordance boundary the
	   plugin derives from --dab-color-text, is deliberately not touched. */
	--dab-color-border: var(--line);

	/* Body and secondary text. */
	--dab-color-text: var(--fg);
	--dab-color-muted: var(--mute);

	/* Validation and unavailable states. */
	--dab-color-danger: var(--urg);
}

/* Filled surfaces. The plugin hard-codes `color:#fff` on every element it fills
 * with --dab-color-primary: .dab-w__btn--primary, .dab-w__day.is-selected,
 * .dab-w__slot.is-active (and its .dab-w__slot-left), .dab-w__clock-btn.is-active
 * and .dab-w__tick. No design token pairs --acc with white -- the design's own
 * rule is `background:var(--acc);color:var(--accfg)` -- and --accfg is #FFFFFF in
 * light mode but #04251B on the dark palette, where white on the mint --acc
 * (#5FE3B8) measures about 1.4:1 and the Book button label, the selected date and
 * the selected time slot stop being readable.
 *
 * Re-pairing those labels with --accfg is a no-op in light mode and restores the
 * contrast in dark mode. The token itself stays mapped to --acc rather than being
 * pinned to the light-mode green, because the plugin also uses primary as a
 * border, an outline and a text colour (.dab-w__slot:hover, .dab-w__nav:hover,
 * .dab-w__back, .dab-w__input:focus-visible), all of which sit on the dark
 * surface and need the light mint there.
 *
 * `.dab-w__success.is-pending .dab-w__tick` (0,3,0) still outranks
 * `body .dab-w__tick` (0,1,1), so the pending amber state is untouched.
 */
body .dab-w__btn--primary,
body .dab-w__day.is-selected,
body .dab-w__slot.is-active,
body .dab-w__slot.is-active .dab-w__slot-left,
body .dab-w__clock-btn.is-active,
body .dab-w__tick {
	color: var(--accfg);
}

/* The widget prints its own `<h2 class="dab-w__heading">` as the first child of
 * `.dab-w` (BookingWidget::render()), falling back to the add-on's configured
 * "Book an appointment" label, so the section override adds no heading of its
 * own. This lifts that heading onto the design's `.h2.sm` type scale -- the
 * element /pages/profile.html uses for every profile section -- with the
 * `0 0 18px` margin the design writes inline there, because the `.card` shell
 * around the widget already supplies the space above it.
 */
body .dab-w__heading {
	margin: 0 0 18px;
	font-family: var(--fd);
	font-size: 22px;
	font-weight: 600;
	letter-spacing: var(--hls);
	line-height: calc(var(--hlh) + .05);
}

/* ---------------------------------------------------------------------------
 * Directorist Smart Assistant — the symptom search widget.
 *
 * The plugin's eight-step teal ramp collapses onto the design's two brand
 * tokens: --acc for anything that reads as the brand, --sky for the secondary
 * and decorative steps, so the widget's 135deg header gradient lands on
 * acc -> sky, the gradient pair the design uses everywhere else. The pale
 * steps become --acc2 (a translucent wash) and --line rather than the plugin's
 * near-white mints, which would glow on the dark palette.
 * ------------------------------------------------------------------------ */

body .dsa-ss {

	/* Brand: strong steps. */
	--dc-teal-800: var(--acc);
	--dc-teal-700: var(--acc);
	--dc-teal-500: var(--acc);

	/* Brand: secondary and decorative steps. */
	--dc-teal-600: var(--sky);
	--dc-teal-400: var(--sky);
	--dc-teal-300: var(--sky);

	/* Brand: washes and pale edges. */
	--dc-teal-200: var(--line);
	--dc-teal-50: var(--acc2);

	/* Urgent. The pale coral wash has no token in the design, so it becomes the
	   raised neutral surface and the signal stays on the border and the icon. */
	--dc-coral-600: var(--urg);
	--dc-coral-500: var(--urg);
	--dc-coral-100: var(--cardS);

	/* Warning. --dc-amber-500 is left at the plugin's amber: the design has no
	   warning colour to map it to. Only its wash is neutralised. */
	--dc-amber-100: var(--cardS);

	/* Text. The design has two levels, so the plugin's four collapse onto them. */
	--dc-ink: var(--fg);
	--dc-ink-70: var(--fg);
	--dc-ink-50: var(--mute);
	--dc-ink-30: var(--mute);

	/* Edges and surfaces. --dc-bg backs the widget's inputs and inset panels,
	   which is what --field is for. */
	--dc-line: var(--line);
	--dc-line-soft: var(--line);
	--dc-surface: var(--card);
	--dc-bg: var(--field);

	/* The outer frame radius; --dc-r-md / -lg stay at the plugin's 16 / 22px,
	   which already sit inside the design's 11px control / 18px card range. */
	--dc-r-xl: var(--r);

	--dc-shadow-lg: var(--shadow);
}

/* ---------------------------------------------------------------------------
 * Symptom search — component skin.
 *
 * The token bridge above carries the palette, but four things the tokens cannot
 * reach still read as another product's widget inside the design's card:
 *
 *   1. The widget draws its own card — surface, border, 30px radius and a deep
 *      shadow — and it sits inside `.ai-card`, which already draws one. Two
 *      nested cards is not the design.
 *   2. Its header is a 135deg teal gradient band with white text. The design has
 *      no gradient bands; its cards are flat surfaces and the accent appears on
 *      controls, not on furniture.
 *   3. Its primary button is CORAL. In this brand coral is reserved for red-flag
 *      symptom warnings and mint is the only call-to-action colour, so an
 *      ordinary "Continue" painted coral reads as an alarm. The red-flag
 *      checklist keeps coral, which is exactly what it is for.
 *   4. Its controls are fully round pills; the design's controls are 11px.
 *
 * Everything here is scoped under `body` to clear the plugin's own
 * single-class rules, and the stylesheet is enqueued after the plugin's so
 * equal-specificity rules fall this way too.
 * ------------------------------------------------------------------------ */

/* `.ai-card` is a centred flex column, so a child with no width set shrinks to
   its own content. The widget host has to claim the full card width or the
   question list ends up half as wide as the card it sits in. */
body .ai-card .ai-widget {
	width: 100%;
	max-width: 760px;
}

/* GeneratePress styles every <button> on the site: `background:#55555e`, and
   `#3f4047` on hover and focus. The widget's own rules mostly set a colour but
   not a background, so on hover that grey — which belongs to neither palette —
   won, and did so identically in light and dark because it is a literal.
   A plain <button> inside the widget is therefore neutralised in every state
   first, and the component rules below paint the ones that need painting.

   Specificity is deliberate: `.dsa-ss button:hover` is (0,2,1), which beats
   GeneratePress' (0,1,1) but only ties the `body .dsa-ss__*` rules below, so
   those still win on source order. Keep this block above them. */
.dsa-ss button,
.dsa-ss button:hover,
.dsa-ss button:focus,
.dsa-ss button:active {
	background-color: transparent;
	color: inherit;
}

body .dsa-ss {
	max-width: 760px;
	color: var(--fg);
	font-family: var(--fb);
	font-size: 1rem;
}

/* 1. One card, not two. The widget becomes part of `.ai-card`. */
body .dsa-ss__frame {
	background-color: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	overflow: visible;
}

body .dsa-ss__body {
	padding: 0;
}

/* 2. The header keeps only the mode switch, centred under the design's own
      eyebrow and heading. `.ai-k` above already names the widget, so the
      widget's duplicate brand line is dropped rather than repeated. */
body .dsa-ss__head {
	justify-content: center;
	padding: 0 0 22px;
	background-image: none;
	color: inherit;
}

body .dsa-ss__brand {
	display: none;
}

/* The mode switch, as the design's `.seg` control. */
body .dsa-ss__tabs {
	gap: 2px;
	padding: 3px;
	border: 1px solid var(--line);
	border-radius: 999px;
	background-color: var(--card);
}

body .dsa-ss__tab {
	min-height: 34px;
	padding: 7px 14px;
	border-radius: 999px;
	font-family: var(--fb);
	font-size: 13px;
	font-weight: 600;
	color: var(--mute);
	transition: background .25s, color .25s;
}

body .dsa-ss__tab:hover {
	background-color: var(--acc2);
	color: var(--fg);
}

body .dsa-ss__tab.is-active,
body .dsa-ss__tab.is-active:hover,
body .dsa-ss__tab.is-active:focus {
	background-color: var(--acc);
	color: var(--accfg);
}

body .dsa-ss__tab.is-active svg {
	color: var(--accfg);
}

/* 3. Buttons, at the design's geometry. */
body .dsa-ss__btn {
	min-height: 46px;
	padding: 0 20px;
	border: 1.5px solid var(--acc);
	border-radius: 11px;
	font-family: var(--fb);
	font-size: 14.5px;
	font-weight: 600;
	transition: transform .25s, box-shadow .25s, background .25s;
}

/* Mint, not coral: this is the call to action, not a warning.
   Every state is named, including the disabled one. The widget disables this
   button until the step is answerable, and a disabled button is still
   hoverable — without the disabled states here the button reverts to the
   neutral reset above and appears to vanish under the cursor. */
body .dsa-ss__btn--accent,
body .dsa-ss__btn--accent:hover,
body .dsa-ss__btn--accent:focus,
body .dsa-ss__btn--accent:active,
body .dsa-ss__btn--accent:disabled,
body .dsa-ss__btn--accent:disabled:hover {
	background-color: var(--acc);
	color: var(--accfg);
	box-shadow: none;
}

body .dsa-ss__btn--accent:hover:not(:disabled) {
	background-color: var(--acc);
	color: var(--accfg);
	transform: translateY(-1px);
	box-shadow: 0 10px 24px -12px var(--acc);
}

body .dsa-ss__btn--ghost,
body .dsa-ss__btn--ghost:disabled,
body .dsa-ss__btn--ghost:disabled:hover {
	background-color: transparent;
	border: 1.5px solid var(--acc);
	color: var(--acc);
}

body .dsa-ss__btn--ghost:hover:not(:disabled) {
	background-color: var(--acc2);
	border-color: var(--acc);
	color: var(--acc);
}

body .dsa-ss__btn:disabled {
	opacity: .45;
}

body .dsa-ss__linkbtn {
	color: var(--acc);
	font-family: var(--fb);
}

/* The send button is a filled circle, not a link: the plugin paints it
 * `background-color:var(--ss-teal-700)`, which the token bridge above resolves to
 * --acc, and hard-codes `color:#fff` on the glyph inside it. Giving the glyph
 * --acc as well would leave accent on accent -- invisible in both colour modes --
 * so it takes the design's own pairing instead: --acc ground, --accfg glyph. The
 * hover step (--ss-teal-800) resolves to --acc too, so it is pinned here as well.
 *
 * The rest of the plugin's hard-coded #fff is already neutralised by the skin
 * below: `.dsa-ss__head` loses its teal gradient and inherits the page colour,
 * `.dsa-ss__brand` is display:none, `.dsa-ss__tab.is-active` and
 * `.dsa-ss__bubble--user` are both re-declared as --acc / --accfg, and
 * `.dsa-ss__btn--accent` likewise. The strong teal steps are therefore NOT
 * swapped for dark brand values in dark mode: --dc-teal-700/-800 are also read as
 * a foreground on the card surface (.dsa-ss__verdict-icon, .dsa-ss__summary-count,
 * .dsa-ss__reason-score, .dsa-ss__summary-edit, .dsa-ss__badge--calm), where the
 * light-mode green would drop to roughly 2:1 on the dark card.
 */
body .dsa-ss__iconbtn,
body .dsa-ss__iconbtn:hover:not(:disabled) {
	background-color: var(--acc);
	color: var(--accfg);
	font-family: var(--fb);
}

/* 4. Fields, at the design's radius and field colour. */
body .dsa-ss__textarea {
	min-height: 92px;
	padding: 18px 20px;
	border: 1.5px solid var(--line);
	border-radius: 22px;
	background-color: var(--field);
	font-family: var(--fb);
	font-size: 16px;
	line-height: 1.5;
	color: var(--fg);
}

body .dsa-ss__input {
	min-height: 46px;
	padding: 0 18px;
	border: 1.5px solid var(--line);
	border-radius: 11px;
	background-color: var(--field);
	font-family: var(--fb);
	font-size: 15px;
	color: var(--fg);
}

body .dsa-ss__textarea:focus,
body .dsa-ss__input:focus {
	background-color: var(--field);
	border-color: var(--acc);
	box-shadow: 0 0 0 5px var(--acc2);
}

body .dsa-ss__textarea::placeholder,
body .dsa-ss__input::placeholder {
	color: var(--mute);
}

/* Chips, as the design's `.chips button`. */
body .dsa-ss__chip {
	min-height: 40px;
	padding: 9px 14px;
	border: 1px solid var(--line);
	border-radius: 999px;
	background-color: var(--card);
	font-family: var(--fb);
	font-size: 14px;
	color: var(--fg);
	transition: border-color .2s, background .2s;
}

body .dsa-ss__chip:disabled,
body .dsa-ss__chip:disabled:hover {
	background-color: var(--card);
	border-color: var(--line);
	color: var(--fg);
}

body .dsa-ss__chip:hover:not(:disabled) {
	border-color: var(--acc);
	background-color: var(--acc2);
	color: var(--fg);
}

body .dsa-ss__chip.is-on {
	border-color: var(--acc);
	background-color: var(--acc2);
	color: var(--fg);
	font-weight: 600;
}

body .dsa-ss__chip--ghost {
	background-color: transparent;
	border-style: dashed;
	color: var(--mute);
}

/* Chat bubbles. The bot speaks on the accent wash, the visitor on the accent. */
body .dsa-ss__bubble {
	border-radius: 16px;
	font-family: var(--fb);
	font-size: 15px;
}

body .dsa-ss__bubble--bot {
	background-color: var(--acc2);
	color: var(--fg);
}

body .dsa-ss__bubble--user {
	background-color: var(--acc);
	color: var(--accfg);
}

body .dsa-ss__bubble--typing span {
	background-color: var(--acc);
}

/* The red-flag checklist keeps coral: that is precisely what coral is for. */
body .dsa-ss__check {
	border-radius: 12px;
	background-color: var(--card);
	font-family: var(--fb);
	font-size: 15px;
	color: var(--fg);
}

body .dsa-ss__check:hover {
	border-color: var(--urg);
	background-color: var(--card);
}

body .dsa-ss__check.is-on,
body .dsa-ss__check.is-on:hover {
	border-color: var(--urg);
	background-color: var(--urg2);
	color: var(--fg);
}

body .dsa-ss__check.is-on .dsa-ss__check-box {
	border-color: var(--urg);
	background-color: var(--urg);
	box-shadow: inset 0 0 0 3px var(--card);
}

body .dsa-ss__check-box {
	border-color: var(--line);
	background-color: var(--field);
}

/* Section headings, summaries and meters. */
body .dsa-ss__section-title,
body .dsa-ss__gate-prompt,
body .dsa-ss__label {
	color: var(--fg);
	font-family: var(--fd);
	font-weight: 600;
}

body .dsa-ss__meter {
	background-color: var(--line);
}

body .dsa-ss__meter-fill {
	background-image: linear-gradient(90deg, var(--acc), var(--sky));
}

body .dsa-ss__progress,
body .dsa-ss__examples-label,
body .dsa-ss__subtitle,
body .dsa-ss__foot-note {
	color: var(--mute);
	font-family: var(--fb);
}

body .dsa-ss__cta {
	border-top-color: var(--line);
}

/* The question panel is the card's own surface. The design puts the form
   directly on `.ai-card`; a second tinted box inside it reads as a nested
   panel that the design does not have. */
body .dsa-ss__panel {
	background-color: transparent;
	border-color: var(--line);
	color: var(--fg);
}

/* The answer recap IS a distinct strip, so it keeps the raised surface. */
body .dsa-ss__summary-head,
body .dsa-ss__summary-row,
body .dsa-ss__recap {
	border-color: var(--line);
	background-color: var(--cardS);
	color: var(--fg);
}

body .dsa-ss__spinner {
	border-top-color: var(--acc);
}

/* The "not connected" notice is an admin-facing state, not a patient one. */
body .dsa-ss__notice {
	border-radius: 12px;
	background-color: var(--acc2);
	color: var(--fg);
}

body .dsa-ss__notice--error {
	background-color: var(--urg2);
	color: var(--fg);
}

@media (max-width: 719.98px) {

	body .dsa-ss__head {
		padding-bottom: 16px;
	}

	body .dsa-ss__tabs {
		width: 100%;
	}
}

/* ---------------------------------------------------------------------------
 * Treatment and city tiles on the Directorist taxonomy screens.
 *
 * The All Categories and All Locations screens render the design's front-page
 * tiles -- `<a class="spec card">` in a `.spec-grid`, `<a class="city card">` in a
 * `.city-grid` (directorist/taxonomies/categories-grid.php and
 * locations-grid.php) -- but the `.spec*` / `.city*` component rules live in
 * assets/css/front-page.css, which inc/enqueue.php loads only inside
 * `if ( dentalpro_is_front_page() )`. Without them every tile is a bare anchor:
 * no padding, no icon chip, no text column, and -- because the design emits those
 * glyphs with no class, relying on `.spec .si svg` / `.city span svg` to size
 * them -- an `<svg>` with no width or height falls back to 150px tall.
 *
 * The two grid containers themselves (`.spec-grid`, `.city-grid`) are in
 * theme.css, which does load there; only the tile components are missing. They
 * are copied below character for character from front-page.css, in source order
 * and inside the same at-rules, so both screens paint exactly what the front page
 * paints. `@keyframes si-wig` and the `container-type` on `.wrap` that the
 * `@container` block queries are both in theme.css already.
 *
 * This file is the only stylesheet the theme loads on a Directorist screen that
 * is not verbatim design CSS, which is why the copy lands here. It is a copy, so
 * it has to be kept in step with front-page.css; the single-source fix is one
 * line in inc/enqueue.php -- enqueue `dentalpro-front-page` from
 * dentalpro_enqueue_directorist() as well -- and this block should be deleted the
 * moment that lands.
 * ------------------------------------------------------------------------ */

.spec{position:relative;display:flex;flex-direction:column;gap:14px;padding:20px;text-decoration:none;overflow:hidden;isolation:isolate}
.spec::before{content:"";position:absolute;inset:0;background:radial-gradient(140px 100px at 18% 0%,var(--acc2),transparent 70%);opacity:0;transition:opacity .4s;z-index:-1}
.spec .si{position:relative;width:48px;height:48px;border-radius:14px;background:linear-gradient(135deg,var(--acc2),transparent);border:1px solid var(--line);color:var(--acc);display:grid;place-items:center;transition:transform .5s cubic-bezier(.34,1.56,.64,1),border-color .3s,background .3s}
.spec .si svg{width:24px;height:24px;transition:color .3s}
.spec .tx{display:flex;flex-direction:column;gap:3px}
.spec b{font-size:16px;font-weight:600;line-height:1.3}
.spec .n{color:var(--mute);font-size:14px;display:flex;gap:6px;align-items:center}
.spec .n [data-n]{font-variant-numeric:tabular-nums;color:var(--fg);font-weight:600}
.spec .go{position:absolute;right:16px;top:18px;width:30px;height:30px;border-radius:50%;border:1px solid var(--line);background:var(--card);color:var(--acc);display:grid;place-items:center;opacity:0;transform:translate(-6px,6px) scale(.8);transition:opacity .3s,transform .45s cubic-bezier(.34,1.56,.64,1)}
.spec .go svg{width:15px;height:15px}
.spec:focus-visible .go{opacity:1;transform:none}
.spec::after{content:"";position:absolute;left:20px;right:20px;bottom:0;height:2px;border-radius:2px;background:linear-gradient(90deg,var(--acc),var(--sky));transform:scaleX(0);transform-origin:left;transition:transform .5s cubic-bezier(.4,0,.2,1)}
@media (prefers-reduced-motion:reduce){
.spec .si,.spec .go,.spec::after{transition:none}
.spec:hover .si svg{animation:none}
}
.city.more-city{border-style:dashed;background:transparent}
.city.more-city b{color:var(--acc)}
.city.more-city span svg:first-child{margin-right:4px}
.city{padding:16px 18px;text-decoration:none;display:flex;justify-content:space-between;align-items:center;gap:10px}
.city b{font-family:var(--fd);font-size:18px;font-weight:700}
.city span{font-size:14px;color:var(--mute);display:flex;gap:8px;align-items:center}
.city span svg{width:16px;height:16px;color:var(--acc);transition:transform .3s}
.city b{font-weight:600}
.spec{padding:22px;min-height:172px;justify-content:space-between}
.spec:nth-child(8n+1),.spec:nth-child(8n+6){background:var(--t1)}
.spec:nth-child(8n+3),.spec:nth-child(8n+8){background:var(--t2)}
.spec:nth-child(8n+4),.spec:nth-child(8n+5){background:var(--t3)}
.spec .si{width:52px;height:52px;border-radius:50%;background:var(--tile);border-color:transparent;box-shadow:0 6px 18px -10px rgba(10,31,27,.25)}
.spec .go{border-color:transparent;background:var(--tile)}
.spec::after{display:none}
.city{padding:20px 22px}
.city:nth-child(3n+2){background:var(--t1)}
.city:nth-child(3n+3){background:var(--t2)}
@media (hover:hover){
.spec:hover::before{opacity:1}
.spec:hover .si{transform:translateY(-3px) rotate(-6deg) scale(1.06);border-color:var(--acc);background:var(--acc)}
.spec:hover .si svg{color:var(--accfg);animation:si-wig .6s cubic-bezier(.34,1.56,.64,1)}
.spec:hover .go{opacity:1;transform:none}
.spec:hover{transform:translateY(-5px)}
.spec:hover::after{transform:scaleX(1)}
.city:hover span svg{transform:translateX(4px)}
}
@container (min-width:300px){
.spec{padding:16px;min-height:150px}
.spec .si{width:44px;height:44px}
.spec .si svg{width:22px;height:22px}
.spec b{font-size:15px}
}
@media (max-width:1023.98px),(pointer:coarse){
.spec .go{opacity:1;transform:none;width:40px;height:40px;right:10px;top:10px}
}
@media (hover:none){
.spec:active{transform:scale(.98);transition:transform 80ms}
}
@media (max-width:719.98px){
.city{padding:16px 18px}
.city b{font-size:16px}
}
