/*
 * 부동산 정보조회 — Phase 2G-C MVP styling.
 *
 * Enough to be clearly usable and nothing more. This is NOT the FirstSelfInt visual identity, and
 * it deliberately imitates no other site: the point of this phase is that the user can read the
 * information and operate the controls, so the next phase can talk about layout with something real
 * in front of it.
 *
 * Everything is scoped under .fsi-app so the plugin cannot restyle the surrounding theme, and every
 * declaration is plain CSS — no build step, no preprocessor, no web font.
 */

.fsi-app {
	--fsi-ink: #1a1a1a;
	--fsi-ink-soft: #5b6470;
	--fsi-line: #dfe3e8;
	--fsi-surface: #ffffff;
	--fsi-surface-soft: #f6f7f9;
	--fsi-accent: #1f5fa8;
	--fsi-notice: #8a6100;
	--fsi-notice-bg: #fff8e6;
	/*
	 * The one emphasised state: 오늘 등록. Deliberately NOT --fsi-ink or the error red (#a4232b) --
	 * reusing the error colour would say "something is wrong" about the freshest thing on the page.
	 * Measured against the card's white background: 5.9:1, and 6.0:1 against its own tint, both
	 * clear of the 4.5:1 minimum for normal text.
	 */
	--fsi-today: #b3181f;
	--fsi-today-bg: #fdecec;

	max-width: 56rem;
	margin: 0 auto;
	padding: 1.25rem 1rem 3rem;
	color: var(--fsi-ink);
	font-size: 1rem;
	line-height: 1.6;
	word-break: keep-all; /* Korean wraps on word boundaries, not mid-word. */
}

.fsi-app *,
.fsi-app *::before,
.fsi-app *::after {
	box-sizing: border-box;
}

/* Focus must be visible for keyboard users; the browser default is kept and strengthened. */
.fsi-app :focus-visible {
	outline: 3px solid var(--fsi-accent);
	outline-offset: 2px;
}

/* --- header ------------------------------------------------------------------ */

.fsi-app__title {
	margin: 0 0 0.25rem;
	font-size: 1.6rem;
	line-height: 1.3;
}

.fsi-app__lede {
	margin: 0 0 1.25rem;
	color: var(--fsi-ink-soft);
}

/* --- search ------------------------------------------------------------------ */

.fsi-search__label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.875rem;
	font-weight: 600;
}

.fsi-search__row {
	display: flex;
	gap: 0.5rem;
}

.fsi-search__input {
	flex: 1 1 auto;
	min-width: 0; /* without this a flex input refuses to shrink below its content on narrow screens */
	padding: 0.7rem 0.85rem;
	font-size: 1rem;
	color: inherit;
	background: var(--fsi-surface);
	border: 1px solid var(--fsi-line);
	border-radius: 6px;
}

.fsi-button {
	flex: 0 0 auto;
	padding: 0.7rem 1.1rem;
	font: inherit;
	font-weight: 600;
	color: var(--fsi-ink);
	background: var(--fsi-surface);
	border: 1px solid var(--fsi-line);
	border-radius: 6px;
	cursor: pointer;
}

.fsi-button:hover {
	background: var(--fsi-surface-soft);
}

.fsi-button[disabled] {
	opacity: 0.6;
	cursor: default;
}

.fsi-button--primary {
	color: #ffffff;
	background: var(--fsi-accent);
	border-color: var(--fsi-accent);
}

.fsi-button--primary:hover {
	background: #194e8a;
}

.fsi-button--ghost {
	margin-bottom: 1rem;
	padding: 0.4rem 0.7rem;
	font-size: 0.875rem;
}

.fsi-button--more {
	display: block;
	width: 100%;
	margin-top: 0.75rem;
}

/* --- status ------------------------------------------------------------------ */

.fsi-status {
	margin: 1rem 0 0;
	min-height: 1.6em; /* reserved, so the layout does not jump when a message appears */
	color: var(--fsi-ink-soft);
	font-size: 0.925rem;
}

/* Never colour alone: the error state also reads as text in the same element. */
.fsi-status--error {
	color: #a4232b;
	font-weight: 600;
}

/* --- results ----------------------------------------------------------------- */

.fsi-results__list {
	margin: 0.75rem 0 0;
	padding: 0;
	list-style: none;
}

.fsi-result + .fsi-result {
	margin-top: 0.5rem;
}

.fsi-result__button {
	display: block;
	width: 100%;
	padding: 0.9rem 1rem;
	font: inherit;
	text-align: start;
	color: inherit;
	background: var(--fsi-surface);
	border: 1px solid var(--fsi-line);
	border-radius: 8px;
	cursor: pointer;
}

.fsi-result__button:hover {
	background: var(--fsi-surface-soft);
	border-color: #c6ccd4;
}

.fsi-result__name {
	display: block;
	font-size: 1.05rem;
	font-weight: 700;
}

.fsi-result__address {
	display: block;
	margin-top: 0.15rem;
	color: var(--fsi-ink-soft);
	font-size: 0.9rem;
}

.fsi-result__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	margin-top: 0.5rem;
}

.fsi-result__chip {
	padding: 0.1rem 0.5rem;
	color: var(--fsi-ink-soft);
	background: var(--fsi-surface-soft);
	border: 1px solid var(--fsi-line);
	border-radius: 999px;
	font-size: 0.8rem;
}

.fsi-result__chip--notice {
	color: var(--fsi-notice);
	background: var(--fsi-notice-bg);
	border-color: #f0dca8;
}

.fsi-result__action {
	display: inline-block;
	margin-top: 0.55rem;
	color: var(--fsi-accent);
	font-size: 0.875rem;
	font-weight: 600;
}

/* --- detail ------------------------------------------------------------------ */

.fsi-detail {
	margin-top: 1.5rem;
}

.fsi-detail__name {
	margin: 0 0 0.25rem;
	font-size: 1.4rem;
}

.fsi-detail__address {
	margin: 0;
	color: var(--fsi-ink-soft);
}

.fsi-detail__address--sub {
	font-size: 0.9rem;
}

/*
 * [2H-L] The trend's PENDING state.
 *
 * The complete sale history is fetched AFTER the first render, so for a moment the chart has nothing
 * to draw. This is deliberately quiet -- the same size and colour as the empty state, italic so it
 * reads as transient rather than as a result. No spinner: a spinner on a section that is not blocking
 * anything invites the reader to wait for it.
 */
.fsi-empty--loading {
	font-style: italic;
	opacity: 0.85;
}

/*
 * [2H-M] Component navigation: where an umbrella apartment's transactions actually live.
 *
 * A short lede and one button per constituent complex, directly under 기본정보 -- above the summary,
 * because a reader who cannot be shown data here should be told where to go before meeting three
 * sections that explain they cannot be shown data here. The buttons reuse `.fsi-button--ghost`, so
 * they inherit the touch target and focus ring the rest of the page already has.
 */
.fsi-components {
	margin-top: 1.25rem;
	padding: 0.9rem 1rem;
	background: var(--fsi-notice-bg);
	border: 1px solid var(--fsi-line);
	border-radius: 8px;
}

.fsi-components__lede {
	margin: 0 0 0.6rem;
	color: var(--fsi-notice);
	font-weight: 600;
}

.fsi-components__list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.fsi-components__item {
	margin: 0;
}

/* One per line on a phone: two Korean complex names side by side do not fit 360px. */
@media (max-width: 32rem) {
	.fsi-components {
		margin-top: 0.85rem;
		padding: 0.7rem 0.75rem;
	}

	.fsi-components__list {
		display: block;
	}

	.fsi-components__item + .fsi-components__item {
		margin-top: 0.4rem;
	}

	.fsi-components__link {
		display: block;
		width: 100%;
	}
}

/* --- DETAIL MODE: the top spacing ------------------------------------------- */

/*
 * Measured on production BEFORE changing anything -- bottom of the sticky site header to the top of
 * `← 검색 결과로`, with the page scrolled to 0 so the number is about layout and not about scroll:
 *
 *     360px  86px      390px  86px      430px  86px      1100px  124px
 *
 * It is four separate boxes, and not one of them carries information in DETAIL MODE:
 *
 *     40px     `.entry-content`'s margin-top -- the THEME's block spacing, sized to sit below the
 *              page title, which detail mode hides outright
 *     8 / 20   `.fsi-app`'s own padding-top
 *     26 / 40  `.fsi-status` -- EMPTY here, and still reserving margin-top plus a min-height that
 *              exists to stop the layout jumping when a SEARCH message appears
 *     12 / 24  `.fsi-detail`'s margin-top -- separation from a status line and a result list that
 *              are not in the layout at all
 *
 * So the space is reserved, not inherited, and each piece is removed where it means nothing rather
 * than pulled back with a negative margin: a negative margin would leave every one of these boxes in
 * place and then subtract a number that has to be re-guessed at each breakpoint, and it would clip
 * the button the moment one of them changed.
 *
 * SEARCH MODE is untouched -- every rule below is gated on `[data-fsi-mode="detail"]`, which `app.js`
 * sets on the way in and clears on the way out. Before the script runs the attribute is absent, so
 * the first paint is search-mode spacing and nothing shifts backwards.
 */

/*
 * The status line keeps its box the moment it has something to say -- `:empty` stops matching as soon
 * as `setStatus()` writes text, which is also why this is not `display: none`: the element stays in
 * the accessibility tree as a live region, so a detail-load error is still announced.
 */
.fsi-app[data-fsi-mode="detail"] .fsi-status:empty {
	margin-top: 0;
	min-height: 0;
}

.fsi-app[data-fsi-mode="detail"] .fsi-detail {
	margin-top: 0;
}

/*
 * The theme's page-content spacing, in detail mode only.
 *
 * `.entry-content` is the app's PARENT, so no selector inside `.fsi-app` can reach it; `:has()` is the
 * same idiom the page-title rule below already uses, fenced the same way -- the stylesheet is enqueued
 * only when the shortcode runs, and a browser without `:has()` simply keeps today's spacing. 0.75rem
 * rather than 0: with `.fsi-app`'s own padding it leaves a modest, ordinary gap below the site header
 * instead of butting the back button against it.
 */
body:has(.fsi-app[data-fsi-mode="detail"]) .entry-content {
	margin-top: 0.75rem;
}

.fsi-card {
	margin-top: 1.25rem;
	padding: 1rem;
	background: var(--fsi-surface-soft);
	border: 1px solid var(--fsi-line);
	border-radius: 8px;
}

.fsi-card__title {
	margin: 0 0 0.6rem;
	font-size: 1rem;
}

.fsi-facts {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 0.35rem 1rem;
	margin: 0;
}

.fsi-facts__term {
	color: var(--fsi-ink-soft);
	font-size: 0.9rem;
}

.fsi-facts__value {
	margin: 0;
	font-weight: 600;
}

/* --- tabs -------------------------------------------------------------------- */

.fsi-tabs {
	margin-top: 1.5rem;
}

.fsi-tabs__list {
	display: flex;
	gap: 0.25rem;
	border-bottom: 2px solid var(--fsi-line);
}

.fsi-tab {
	padding: 0.6rem 0.9rem;
	font: inherit;
	font-weight: 600;
	color: var(--fsi-ink-soft);
	background: none;
	border: 0;
	border-bottom: 3px solid transparent;
	margin-bottom: -2px;
	cursor: pointer;
}

/* The selected tab is marked by weight and an underline, not by colour alone. */
.fsi-tab[aria-selected="true"] {
	color: var(--fsi-ink);
	border-bottom-color: var(--fsi-accent);
}

.fsi-tabs__panel {
	padding-top: 1rem;
}

/* --- sections and tables ------------------------------------------------------ */

.fsi-section__count {
	margin: 0 0 0.5rem;
	color: var(--fsi-ink-soft);
	font-size: 0.875rem;
}

/*
 * A transaction table has six columns of real numbers and cannot honestly shrink to 360px, so it
 * scrolls horizontally INSIDE this box rather than pushing the whole page sideways. Marked
 * focusable so a keyboard user can scroll it too.
 */
.fsi-table-scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.fsi-table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.925rem;
	white-space: nowrap;
}

.fsi-table th,
.fsi-table td {
	padding: 0.5rem 0.65rem;
	text-align: start;
	border-bottom: 1px solid var(--fsi-line);
}

.fsi-table th {
	color: var(--fsi-ink-soft);
	font-size: 0.85rem;
	font-weight: 600;
	background: var(--fsi-surface-soft);
}

.fsi-table__amount {
	font-variant-numeric: tabular-nums;
	font-weight: 600;
}

.fsi-table__area-label {
	display: inline-block;
	font-weight: 600;
}

.fsi-badge {
	display: inline-block;
	padding: 0.05rem 0.4rem;
	border-radius: 4px;
	font-size: 0.8rem;
	font-weight: 600;
}

.fsi-badge--cancelled {
	color: #a4232b;
	background: #fdecec;
}

/* --- notices ------------------------------------------------------------------ */

.fsi-notice {
	margin: 0.75rem 0 0;
	padding: 0.7rem 0.85rem;
	color: var(--fsi-notice);
	background: var(--fsi-notice-bg);
	border: 1px solid #f0dca8;
	border-radius: 6px;
	font-size: 0.9rem;
}

.fsi-notice--review {
	margin-top: 0;
}

.fsi-empty {
	margin: 0;
	color: var(--fsi-ink-soft);
}

.fsi-footnote {
	margin: 0.6rem 0 0;
	color: var(--fsi-ink-soft);
	font-size: 0.825rem;
}

/* --- permits ------------------------------------------------------------------ */

.fsi-permits {
	margin: 0;
	padding: 0;
	list-style: none;
}

.fsi-permit {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	padding: 0.6rem 0;
	border-bottom: 1px solid var(--fsi-line);
}

.fsi-permit__date {
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.fsi-permit__status {
	padding: 0.05rem 0.45rem;
	background: var(--fsi-surface-soft);
	border: 1px solid var(--fsi-line);
	border-radius: 999px;
	font-size: 0.85rem;
}

.fsi-permit__purpose,
.fsi-permit__address {
	color: var(--fsi-ink-soft);
	font-size: 0.9rem;
}

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

/*
 * 32rem = 512px. Chosen over 480px for a testable reason: headless Chrome enforces a MINIMUM
 * viewport of 500px without a CDP driver, so a 480px breakpoint could never be exercised by the
 * browser suite -- it was being asserted by reading the stylesheet rather than by rendering it. At
 * 512px the narrow layout is genuinely rendered and checked, and every width below it (360px
 * included) gets the same treatment.
 */
@media (max-width: 32rem) {
	/*
	 * [Phase 2H-D] The page TITLE, on phones only.
	 *
	 * Measured on the real site at 360px before touching anything: the theme renders the page title
	 * at 38px with 36px of padding above and below -- 129px tall -- and the apartment name then sits
	 * 544px down the page, with 기본정보 at 666px. On a phone that is most of the first screen spent
	 * before any apartment information appears, which is exactly the real-device complaint.
	 *
	 * This is the one rule in this stylesheet that reaches outside `.fsi-app`, and it is fenced three
	 * ways rather than loosened: the stylesheet is enqueued only when the shortcode runs; `:has()`
	 * makes the rule self-scoping, so it applies only on a document that actually contains the app;
	 * and it lives below 32rem, so desktop keeps the theme's own typography untouched.
	 *
	 * `:has()` rather than a body class added from PHP. A `body_class` filter would have been the
	 * conventional route, but the UI suite asserts that this plugin "registers exactly one shortcode
	 * and no other WordPress surface" -- a guard worth more than the convenience, and one this
	 * change tripped before being rewritten this way. A browser without `:has()` simply ignores the
	 * rule and gets today's layout, which is a safe degradation.
	 *
	 * `!important` is required on BOTH declarations and is not laziness. The padding is an INLINE
	 * style (`style="padding-top:var(--wp--preset--spacing--60);..."`), which no stylesheet rule can
	 * otherwise outrank. The size comes from WordPress's `has-x-large-font-size` preset utility,
	 * which the block theme itself declares with `!important` -- measured on production, where a
	 * plain `font-size` left the heading at 38px while the padding fix had already applied.
	 *
	 * The heading stays clearly a heading -- 1.6rem against 1rem body text -- rather than shrinking
	 * toward body size.
	 */
	body:has(.fsi-app) h1.wp-block-post-title {
		padding-top: 0.5rem !important;
		padding-bottom: 0.5rem !important;
		font-size: 1.6rem !important;
		line-height: 1.3;
	}

	.fsi-app {
		/* Was 1rem. The title above now ends much closer, so the container's own top padding is
		   what remains between them; 0.5rem keeps them distinct without a gap. */
		padding: 0.5rem 0.75rem 2.5rem;
	}

	/*
	 * The instruction text keeps its size on purpose. The brief is explicit that
	 * "아파트 이름 또는 주소를 검색하세요." must stay comfortably readable, so only the space around
	 * it is reduced -- never its font size.
	 */
	.fsi-app__lede {
		margin-bottom: 0.75rem;
	}

	.fsi-app__title {
		font-size: 1.35rem;
	}

	/* The button drops below the field rather than squeezing it to nothing. */
	.fsi-search__row {
		flex-wrap: wrap;
	}

	.fsi-search__input {
		flex: 1 1 100%;
	}

	.fsi-button--primary {
		flex: 1 1 100%;
	}

	.fsi-facts {
		grid-template-columns: 1fr;
		gap: 0 0;
	}

	.fsi-facts__term {
		margin-top: 0.5rem;
	}

	.fsi-tabs__list {
		overflow-x: auto;
	}
}

@media (prefers-reduced-motion: reduce) {
	.fsi-app * {
		scroll-behavior: auto;
	}
}

/* ===========================================================================
 * Phase 2G-C2 — recent activity, trend chart, 신고가 badge
 * =========================================================================== */

/* --- recent activity ------------------------------------------------------ */

.fsi-activity {
	margin-top: 1.5rem;
}

.fsi-activity__header {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5rem;
	margin-bottom: 0.6rem;
}

.fsi-activity__title {
	margin: 0;
	font-size: 1rem;
}

.fsi-activity__asof {
	color: var(--fsi-ink-soft);
	font-size: 0.8rem;
}

/* Two cards side by side on desktop; they stack below 30rem (see the media query). */
.fsi-activity__cards {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0.75rem;
}

.fsi-activity__card {
	padding: 0.9rem 1rem;
	background: var(--fsi-surface);
	border: 1px solid var(--fsi-line);
	border-radius: 8px;
	text-align: center;
}

.fsi-activity__card-title {
	margin: 0 0 0.5rem;
	color: var(--fsi-ink-soft);
	font-size: 0.875rem;
	font-weight: 600;
}

.fsi-activity__value {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.35rem;
	margin: 0 0 0.4rem;
	font-size: 1.35rem;
	font-weight: 700;
	line-height: 1.2;
}

.fsi-activity__value--muted {
	color: var(--fsi-ink-soft);
	font-size: 1.05rem;
	font-weight: 600;
}

/*
 * 오늘 등록, and nothing else.
 *
 * A compact tinted chip around the value that is already there -- not a larger value, not a second
 * element, and not the card. `.fsi-activity__value` is already `font-weight: 700`, so weight cannot
 * carry the emphasis on its own and the colour is what makes it read as today; the WORDS still say
 * 오늘 등록, so nothing is conveyed by colour alone. `1일 전 등록`, `2일 전 등록` and
 * `등록일 확인 불가` inherit the ordinary style untouched, which is the whole point of scoping this
 * to one modifier class set at the call site.
 *
 * The padding is horizontal-only and the line-height is not raised, so the chip adds no vertical
 * space and cannot move the card's own height -- verified at 360/390/430 px.
 */
.fsi-activity__relative--today {
	padding: 0 0.4rem;
	border-radius: 5px;
	background: var(--fsi-today-bg);
	color: var(--fsi-today);
}

.fsi-activity__label {
	margin: 0;
	color: var(--fsi-ink-soft);
	font-size: 0.8rem;
}

.fsi-activity__date {
	margin: 0;
	font-size: 0.95rem;
	font-variant-numeric: tabular-nums;
}

.fsi-activity__note {
	margin: 0;
	color: var(--fsi-ink-soft);
	font-size: 0.8rem;
}

/* --- trend chart ---------------------------------------------------------- */

.fsi-trend {
	margin-top: 1.5rem;
	padding: 1rem;
	background: var(--fsi-surface);
	border: 1px solid var(--fsi-line);
	border-radius: 8px;
}

.fsi-trend__header {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5rem;
}

.fsi-trend__title {
	margin: 0 0 0.75rem;
	font-size: 1rem;
}

.fsi-trend__controls {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1.25rem;
	margin-bottom: 0.75rem;
}

.fsi-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
}

.fsi-chip {
	min-height: 2.2rem;      /* ~35px; with the padding below the touch target clears 44px */
	padding: 0.35rem 0.7rem;
	font: inherit;
	font-size: 0.875rem;
	color: var(--fsi-ink-soft);
	background: var(--fsi-surface-soft);
	border: 1px solid var(--fsi-line);
	border-radius: 999px;
	cursor: pointer;
}

.fsi-chip:hover {
	border-color: #c6ccd4;
}

/* The pressed state is the accessible state: styling follows aria-pressed rather than a class. */
.fsi-chip[aria-pressed="true"] {
	color: #ffffff;
	background: var(--fsi-accent);
	border-color: var(--fsi-accent);
	font-weight: 600;
}

.fsi-chart-wrap {
	margin: 0;
}

.fsi-chart {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

.fsi-chart__grid {
	stroke: var(--fsi-line);
	stroke-width: 1;
}

.fsi-chart__axis {
	fill: var(--fsi-ink-soft);
	font-size: 11px;
	font-family: inherit;
}

.fsi-chart__point {
	cursor: pointer;
}

.fsi-chart__point:hover,
.fsi-chart__point:focus-visible {
	stroke: var(--fsi-ink);
	stroke-width: 2;
}

.fsi-chart__readout {
	min-height: 1.4em;
	margin: 0.35rem 0 0;
	color: var(--fsi-ink-soft);
	font-size: 0.85rem;
}

.fsi-legend {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 0.9rem;
	margin: 0.5rem 0 0;
	padding: 0;
	list-style: none;
}

.fsi-legend__item {
	display: flex;
	align-items: center;
	gap: 0.35rem;
	font-size: 0.825rem;
	color: var(--fsi-ink-soft);
}

.fsi-legend__swatch {
	width: 0.7rem;
	height: 0.7rem;
	border-radius: 2px;
}

.fsi-trend__count {
	margin: 0.5rem 0 0;
	color: var(--fsi-ink-soft);
	font-size: 0.825rem;
}

/* --- 신고가 --------------------------------------------------------------- */

/*
 * A compact badge beside the amount. It reads 신고가 as text, so the meaning survives without
 * colour; the red is emphasis, not information.
 */
.fsi-badge--record {
	margin-inline-end: 0.35rem;
	padding: 0.05rem 0.35rem;
	color: #a4232b;
	background: #fdecec;
	border: 1px solid #f3c9c9;
	border-radius: 4px;
	font-size: 0.75rem;
	font-weight: 700;
	white-space: nowrap;
}

.fsi-table__amount-value {
	white-space: nowrap;
}

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

@media (max-width: 32rem) {
	.fsi-activity__cards {
		grid-template-columns: 1fr;
	}

	.fsi-trend {
		padding: 0.75rem;
	}

	.fsi-trend__controls {
		gap: 0.5rem 0.75rem;
	}

	.fsi-chart {
		/* Keeps points and labels legible at 360px instead of squeezing the whole plot. */
		min-height: 200px;
	}
}

/* ===========================================================================
 * Phase 2G-C3 — search autocomplete, and a readable transaction row on a phone
 * =========================================================================== */

/* --- autocomplete --------------------------------------------------------- */

/*
 * The field wraps the input AND the panel, so the panel is anchored to the input rather than to the
 * page. It stays aligned at any width, with no fixed pixel offsets to break on another screen.
 */
.fsi-search__field {
	position: relative;
	flex: 1 1 auto;
	min-width: 0;
}

.fsi-search__field .fsi-search__input {
	width: 100%;
}

/*
 * A small, local stacking context — enough to sit above the chart and the cards below, and nowhere
 * near a global z-index war. 20 beats everything this plugin renders and nothing else.
 */
.fsi-suggest {
	position: absolute;
	z-index: 20;
	top: calc(100% + 0.25rem);
	inset-inline: 0;
	/*
	 * Tall enough for the full suggestion limit on a phone (6 items x ~60px), but never more than
	 * 60% of the viewport -- so it still scrolls rather than filling the screen when a soft keyboard
	 * has shrunk the visible area. At 21rem the sixth row was clipped mid-item, which reads as a
	 * rendering fault rather than as a scroll affordance.
	 */
	max-height: min(24rem, 60vh);
	overflow-y: auto;
	margin: 0;
	padding: 0.25rem;
	list-style: none;
	background: var(--fsi-surface);
	border: 1px solid #c6ccd4;
	border-radius: 8px;
	box-shadow: 0 6px 18px rgba(16, 24, 40, 0.12);
}

.fsi-suggest__item {
	display: block;
	/* ~44px of touch target once padding is counted. */
	min-height: 2.75rem;
	padding: 0.5rem 0.6rem;
	border-radius: 6px;
	cursor: pointer;
}

.fsi-suggest__item:hover,
.fsi-suggest__item.is-active {
	background: var(--fsi-surface-soft);
}

/* The active option is outlined as well as tinted, so it is not signalled by colour alone. */
.fsi-suggest__item.is-active {
	box-shadow: inset 0 0 0 2px var(--fsi-accent);
}

.fsi-suggest__name {
	display: block;
	font-weight: 700;
	line-height: 1.35;
	overflow-wrap: anywhere;   /* a long Korean name wraps rather than widening the panel */
}

.fsi-suggest__address {
	display: block;
	margin-top: 0.1rem;
	color: var(--fsi-ink-soft);
	font-size: 0.85rem;
	line-height: 1.35;
	overflow-wrap: anywhere;
}

.fsi-suggest__message {
	padding: 0.6rem;
	color: var(--fsi-ink-soft);
	font-size: 0.9rem;
}

/* ---------------------------------------------------------------------------
 * Narrow-screen transactions
 *
 * The desktop table is kept exactly as it is above 32rem. Below it, the SAME markup becomes a
 * two-line card through CSS alone — one semantic dataset, one set of DOM nodes, so a row appended
 * later by 더 보기 is laid out identically and a 신고가 badge is literally the same element on both
 * presentations. There is no second renderer to drift.
 *
 * Measured problem this solves, at a real 360px viewport: the table scroller was 276px wide with
 * 445px of content, and the amount cell's right edge sat at 466px — the price was off-screen behind
 * a horizontal scroller.
 * --------------------------------------------------------------------------- */

@media (max-width: 32rem) {

	/* The scroller stops scrolling: nothing overflows any more. */
	.fsi-table-scroll {
		overflow-x: visible;
	}

	.fsi-table,
	.fsi-table tbody,
	.fsi-table tr,
	.fsi-table td {
		display: block;
		width: auto;
	}

	/* Column headings describe a grid that no longer exists at this width. */
	.fsi-table thead {
		display: none;
	}

	.fsi-table {
		white-space: normal;   /* nowrap is what forced the overflow */
	}

	.fsi-table tr {
		display: grid;
		grid-template-columns: auto auto 1fr;
		align-items: baseline;
		column-gap: 0.4rem;
		row-gap: 0.15rem;
		padding: 0.6rem 0.1rem;
		border-bottom: 1px solid var(--fsi-line);
	}

	.fsi-table td {
		padding: 0;
		border: 0;
	}

	/*
	 * Sale row:   date ............................ amount
	 *             area   floor ..................... (해제)
	 * Rent row:   date ............................ 구분
	 *             area   floor ..................... 보증금
	 *                                               월세
	 */
	.fsi-table__date {
		grid-column: 1 / 3;
		grid-row: 1;
		color: var(--fsi-ink-soft);
		font-variant-numeric: tabular-nums;
	}

	.fsi-table__area {
		grid-column: 1;
		grid-row: 2;
	}

	.fsi-table__floor {
		grid-column: 2;
		grid-row: 2;
		color: var(--fsi-ink-soft);
	}

	/* The price is the primary value on the row, so it is the largest thing on it. */
	.fsi-table tbody tr > .fsi-table__amount:first-of-type {
		grid-column: 3;
		grid-row: 1;
		justify-self: end;
		font-size: 1.05rem;
	}

	.fsi-table__flag,
	.fsi-table__type,
	.fsi-table tbody tr > .fsi-table__amount ~ .fsi-table__amount {
		grid-column: 3;
		justify-self: end;
	}

	.fsi-table__flag {
		grid-row: 2;
	}

	/* Rent: 구분 sits beside the date, the deposit takes the price slot, 월세 goes under it. */
	.fsi-table__type {
		grid-row: 1;
		color: var(--fsi-ink-soft);
		font-size: 0.85rem;
	}

	.fsi-table tbody tr > .fsi-table__type ~ .fsi-table__amount:first-of-type {
		grid-row: 2;
	}

	.fsi-table tbody tr > .fsi-table__amount ~ .fsi-table__amount {
		grid-row: 3;
		font-size: 0.9rem;
		color: var(--fsi-ink-soft);
	}

	/* 전세 has no monthly rent; the placeholder dash is noise once 구분 already says 전세. */
	.fsi-table__amount--none {
		display: none;
	}

	.fsi-table__area-label {
		font-weight: 700;
	}

	/* The badge sits with the price and wraps above it rather than pushing it off the row. */
	.fsi-table tbody tr > .fsi-table__amount:first-of-type {
		display: flex;
		flex-wrap: wrap;
		justify-content: flex-end;
		align-items: baseline;
		gap: 0.25rem;
	}

	.fsi-permit {
		gap: 0.25rem 0.5rem;
	}

	.fsi-permit__address {
		flex-basis: 100%;   /* the address gets its own line instead of stretching the row */
	}
}

/* ===========================================================================
 * Phase 2G-C4 — a denser mobile summary above the chart
 *
 * The problem, measured at a real 360px viewport before this block existed: 기본정보 was 288px tall
 * and 최근 거래 현황 305px, so the trend chart began 792px below the detail heading and the
 * transaction tabs 1323px below it — roughly two screenfuls of scrolling before any transaction.
 *
 * Nothing is removed to fix that. Every field, label, date and state that was on the page is still
 * on the page; only layout, repetition and whitespace are compressed.
 * =========================================================================== */

/* --- shared structure ----------------------------------------------------- */

/*
 * The term/value pairs are wrapped in `.fsi-fact`, which desktop dissolves with `display: contents`
 * so the `dt`/`dd` stay direct grid items of `.fsi-facts` and the label column keeps its shared
 * width — desktop renders exactly as it did in C3. The narrow layout below turns the wrapper into a
 * real box and puts two pairs on a line.
 */
.fsi-fact {
	display: contents;
}

/* Desktop keeps the label and the date on separate lines, as in C2/C3. */
.fsi-activity__meta {
	margin: 0;
}

.fsi-activity__label,
.fsi-activity__date {
	display: block;
}

/* --- narrow screens: the compression ---------------------------------------- */

@media (max-width: 32rem) {

	/* The empty status line and the detail's top margin together cost ~40px of dead space above
	   the apartment name on a phone, for no information. */
	.fsi-status {
		margin-top: 0.5rem;
		min-height: 1.2em;
	}

	.fsi-detail {
		margin-top: 0.75rem;
	}

	.fsi-results {
		margin-top: 0.25rem;
	}

	/* Identity: still prominent, just not a hero block. */
	.fsi-detail__name {
		font-size: 1.2rem;
		line-height: 1.3;
		overflow-wrap: anywhere;   /* a long Korean name wraps instead of overflowing */
	}

	.fsi-detail__address {
		font-size: 0.875rem;
		line-height: 1.4;
	}

	.fsi-detail__address--sub {
		font-size: 0.8rem;
	}

	.fsi-button--ghost {
		margin-bottom: 0.5rem;
	}

	/* --- 기본정보: two pairs per line ---------------------------------------- */

	.fsi-card {
		margin-top: 0.75rem;
		padding: 0.7rem 0.75rem;
	}

	.fsi-card__title {
		margin-bottom: 0.5rem;
		font-size: 0.9rem;
	}

	.fsi-facts {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0.55rem 0.75rem;
	}

	.fsi-fact {
		display: block;   /* the wrapper becomes the grid cell: label above value */
		min-width: 0;
	}

	.fsi-facts__term {
		margin: 0 0 0.1rem;
		font-size: 0.75rem;
		line-height: 1.3;
	}

	.fsi-facts__value {
		font-size: 0.95rem;
		line-height: 1.35;
		/*
		 * Several area groups wrap inside the value rather than widening the page — but at the
		 * separators, not mid-token. `anywhere` split "114㎡" and left a lone ㎡ on its own line;
		 * `break-word` prefers the existing break opportunities around " · " and only splits a
		 * single token if one is genuinely too long to fit.
		 */
		overflow-wrap: break-word;
	}

	/* --- 최근 거래 현황: two cards side by side ------------------------------- */

	.fsi-activity {
		margin-top: 0.85rem;
	}

	.fsi-activity__header {
		margin-bottom: 0.4rem;
	}

	.fsi-activity__title {
		font-size: 0.9rem;
	}

	.fsi-activity__asof {
		font-size: 0.7rem;
	}

	/* Side by side even at 360px — this is the single biggest saving, and the cards hold little
	   enough text to stay readable at half width. */
	.fsi-activity__cards {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0.5rem;
	}

	.fsi-activity__card {
		padding: 0.55rem 0.5rem;
	}

	.fsi-activity__card-title {
		margin-bottom: 0.25rem;
		font-size: 0.78rem;
	}

	.fsi-activity__value {
		margin-bottom: 0.2rem;
		font-size: 1.15rem;
	}

	.fsi-activity__value--muted {
		font-size: 0.9rem;
	}

	/* Label and date share one line: "최근 계약일 2026.09.18". The wording is unchanged — only the
	   line break is gone. It still wraps rather than clipping if a value is long. */
	.fsi-activity__label,
	.fsi-activity__date {
		display: inline;
		font-size: 0.75rem;
	}

	.fsi-activity__label::after {
		content: ' ';
	}

	.fsi-activity__date {
		font-weight: 600;
		white-space: nowrap;   /* a date is never a useful place to break */
	}

	.fsi-activity__note {
		font-size: 0.75rem;
	}

	/* --- 실거래가 추이: tighter frame, same chart ------------------------------ */

	.fsi-trend {
		margin-top: 0.85rem;
		padding: 0.7rem 0.6rem;
	}

	.fsi-trend__title {
		margin-bottom: 0.5rem;
		font-size: 0.9rem;
	}

	.fsi-trend__controls {
		gap: 0.4rem 0.6rem;
		margin-bottom: 0.5rem;
	}

	.fsi-trend__count,
	.fsi-footnote {
		font-size: 0.75rem;
	}

	/* --- tabs: closer, but not smaller to touch -------------------------------- */

	.fsi-tabs {
		margin-top: 0.9rem;
	}

	.fsi-tabs__panel {
		padding-top: 0.6rem;
	}

	.fsi-notice {
		padding: 0.55rem 0.65rem;
		font-size: 0.85rem;
	}
}
