/*
 * Gitea Cards — styles
 *
 * Card, chip, and badge rules are added by the feature tickets (F1–F8).
 * Keep all styling here as CSS classes driven by Obsidian CSS variables;
 * the plugin must not set inline styles (community-review guideline).
 */

.gitea-card {
	border: 1px solid var(--background-modifier-border);
	border-radius: var(--radius-m);
	padding: var(--size-4-2) var(--size-4-3);
	background-color: var(--background-secondary);
}

/* Per-project accent (issue #19): a subtle coloured left border, driven by the
 * --gitea-accent custom property the plugin sets per repo. The repo-less default
 * keeps the neutral border, so only configured projects are tinted. */
.gitea-card--accented {
	border-left: 3px solid var(--gitea-accent, var(--background-modifier-border));
}

.gitea-card--closed {
	opacity: 0.6;
}

/* Closed issues read as resolved at a glance — strike the title through */
.gitea-card--closed .gitea-card__title {
	text-decoration: line-through;
}

.gitea-card--stale {
	opacity: 0.5;
	border-style: dashed;
}

/* Stale badge — shown when a card falls back to last-known data offline */
.gitea-card__stale-badge {
	flex-shrink: 0;
	margin-left: auto;
	padding: 0 var(--size-4-1);
	border-radius: var(--radius-s);
	background-color: var(--background-modifier-border);
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	/* Intra-token break lock lives in the shared theme-proof rule below. */
}

.gitea-card--loading,
.gitea-card--error,
.gitea-card--empty {
	color: var(--text-muted);
	font-size: var(--font-ui-small);
}

.gitea-card--error {
	color: var(--text-error);
}

/* Line 1 — number link + title */
.gitea-card__header {
	display: flex;
	align-items: baseline;
	gap: var(--size-4-2);
}

.gitea-card__number {
	flex-shrink: 0;
	font-weight: var(--font-semibold);
	font-variant-numeric: tabular-nums;
	/* A number like #21 is one indivisible token — never let a narrow phone
	 * width (or a theme that boxes it into a tight pill) split it mid-token.
	 * The break lock lives in the shared theme-proof rule below. */
}

.gitea-card__title {
	font-weight: var(--font-medium);
}


/* Search block — a vertical list of cards. Positioning context for the
   corner-pinned refresh button (issue #45). */
.gitea-search {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--size-4-2);
}

.gitea-search__notice {
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
}

/* Search toolbar (issue #35, #36) — right-aligned "Refresh" and "Add issue"
   buttons. Refresh forces a fresh fetch; Add issue opens the new-issue form
   prefilled from the query. */
.gitea-search__toolbar {
	display: flex;
	justify-content: flex-end;
	gap: var(--size-4-2);
}

/* Search table (issue #33) — a compact, chip-like grid of results so the
   progress of a set of issues reads at a glance, the default search layout. */
.gitea-search-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--font-ui-small);
	font-variant-numeric: tabular-nums;
}

.gitea-search-table__row {
	border-bottom: 1px solid var(--background-modifier-border);
}

.gitea-search-table__row:last-child {
	border-bottom: none;
}

.gitea-search-table__row:hover {
	background-color: var(--background-modifier-hover);
}

.gitea-search-table__row--closed {
	opacity: 0.6;
}

/* Per-project accent (issue #30): a coloured left edge mirroring the cards. */
.gitea-search-table__row--accented .gitea-search-table__cell--dot {
	border-left: 3px solid var(--gitea-accent, var(--background-modifier-border));
}

.gitea-search-table__cell {
	padding: var(--size-4-1) var(--size-4-2);
	vertical-align: middle;
	text-align: left;
}

.gitea-search-table__cell--dot {
	width: 1em;
	padding-right: 0;
}

.gitea-search-table__dot {
	display: inline-block;
	width: 0.55em;
	height: 0.55em;
	border-radius: 50%;
	background-color: var(--text-muted);
}

.gitea-search-table__dot--open {
	background-color: var(--color-green);
}

.gitea-search-table__dot--closed {
	background-color: var(--color-red);
}

.gitea-search-table__dot--in-progress {
	background-color: var(--color-orange);
}

.gitea-search-table__cell--number {
	white-space: nowrap;
	width: 1%;
}

.gitea-search-table__number {
	text-decoration: none;
	color: var(--text-muted);
	/* #21 is one indivisible token. The cell sets nowrap, but mobile themes that
	 * restyle the inner link into a pill target this element directly and can
	 * override the cell's value — the shared theme-proof rule below locks all
	 * three intra-token break properties to win the cascade. */
}

.gitea-search-table__number:hover {
	color: var(--text-accent);
	text-decoration: none;
}

.gitea-search-table__cell--repo {
	white-space: nowrap;
	width: 1%;
	color: var(--text-muted);
}

/* Title takes the remaining width and truncates so a long title can't blow out
   the row — the same restraint the inline chip title uses. */
.gitea-search-table__cell--title {
	width: 100%;
	max-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.gitea-search-table__cell--state {
	white-space: nowrap;
	width: 1%;
	text-align: right;
}

/* Status badge, mirroring the inline chip's state pill. */
.gitea-search-table__state {
	padding: 0 var(--size-4-1);
	border-radius: var(--radius-s);
	background-color: var(--background-modifier-border);
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
	font-weight: var(--font-semibold);
	letter-spacing: 0.02em;
	text-transform: uppercase;
	/* CLOSED must never split to CLOS / ED. A plain nowrap (set previously) lost
	 * to the user's mobile theme, which floats this badge into a tight top-right
	 * pill and resets the break behaviour — the shared theme-proof rule below
	 * forces all three break properties to stay whole regardless of theme. */
}

.gitea-search-table__state--open {
	background-color: var(--color-green);
	color: var(--text-on-accent);
}

.gitea-search-table__state--closed {
	background-color: var(--color-red);
	color: var(--text-on-accent);
}

.gitea-search-table__state--in-progress {
	background-color: var(--color-orange);
	color: var(--text-on-accent);
}

/* Line 2 — truncated body */
.gitea-card__body {
	margin-top: var(--size-4-1);
	color: var(--text-muted);
	font-size: var(--font-ui-small);
}

/* Line 3 — labels, author, milestone */
.gitea-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--size-4-2);
	margin-top: var(--size-4-2);
	font-size: var(--font-ui-smaller);
}

.gitea-card__labels {
	display: flex;
	flex-wrap: wrap;
	gap: var(--size-4-1);
}

.gitea-card__label {
	padding: 0 var(--size-4-2);
	border-radius: var(--radius-s);
	background-color: var(--gitea-label-bg, var(--background-modifier-border));
	color: var(--gitea-label-fg, var(--text-normal));
	font-size: var(--font-ui-smaller);
	line-height: 1.6;
	/* Labels wrap *between* chips (the row flex-wraps), but an individual label
	 * name shouldn't split mid-word. */
	white-space: nowrap;
}

/* blocked-by:#N dependency chips — highlighted so blockers stand out, with the
 * blocker's live state shown inline via the dot below. */
.gitea-card__label--blocked-by {
	display: inline-flex;
	align-items: center;
	gap: var(--size-4-1);
	background-color: var(--background-modifier-error);
	color: var(--text-normal);
	font-weight: var(--font-medium);
}

/* The blocker has closed — the dependency is cleared, so de-emphasise it */
.gitea-card__label--resolved {
	background-color: var(--background-modifier-success);
	font-weight: var(--font-normal);
	text-decoration: line-through;
	opacity: 0.85;
}

/* Inline blocker-state dot. Semantics are the inverse of a card's own state
 * dot: an open blocker is still blocking (red), a closed one is cleared (green). */
.gitea-card__blocker-dot {
	width: 0.55em;
	height: 0.55em;
	border-radius: 50%;
	background-color: var(--text-muted);
}

.gitea-card__blocker-dot--open {
	background-color: var(--color-red);
}

.gitea-card__blocker-dot--closed {
	background-color: var(--color-green);
}

.gitea-card__author,
.gitea-card__milestone,
.gitea-card__repo-name,
.gitea-card__comments,
.gitea-card__state,
.gitea-card__updated {
	display: inline-flex;
	align-items: center;
	gap: var(--size-4-1);
	color: var(--text-muted);
}

/* The open/closed state badge is a short word (OPEN / CLOSED) — keep it whole
 * so a narrow phone width or a theme that floats it into a tight pill can't
 * break it mid-token (e.g. CLOS / ED). The break lock lives in the shared
 * theme-proof rule below. */

/* Repo identity at the front of the status row (issue #22) */
.gitea-card__repo-name {
	font-variant-numeric: tabular-nums;
	text-decoration: none;
}

.gitea-card__repo-name:hover {
	color: var(--text-normal);
	text-decoration: underline;
}

.gitea-card__avatar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.4em;
	height: 1.4em;
	border-radius: 50%;
	background-color: var(--background-modifier-border);
	color: var(--text-normal);
	font-size: var(--font-ui-smaller);
	font-weight: var(--font-semibold);
}

/* Line 4 — comments, state, updated */
.gitea-card__status {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--size-4-3);
	margin-top: var(--size-4-1);
	font-size: var(--font-ui-smaller);
}

.gitea-card__dot {
	width: 0.6em;
	height: 0.6em;
	border-radius: 50%;
	background-color: var(--text-muted);
}

.gitea-card__dot--open {
	background-color: var(--color-green);
}

.gitea-card__dot--closed {
	background-color: var(--color-red);
}

/* Milestone progress block */
.gitea-milestone__header {
	display: flex;
	align-items: baseline;
	gap: var(--size-4-2);
}

.gitea-milestone__title {
	font-weight: var(--font-medium);
}

.gitea-milestone__percent {
	flex-shrink: 0;
	margin-left: auto;
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
	font-variant-numeric: tabular-nums;
}

/* Track + fill — fill width is driven by the --gitea-progress custom property
 * the plugin sets per render (no inline style rules, like the label chips). */
.gitea-milestone__bar {
	margin-top: var(--size-4-2);
	height: var(--size-4-2);
	border-radius: var(--radius-s);
	background-color: var(--background-modifier-border);
	overflow: hidden;
}

.gitea-milestone__bar-fill {
	width: var(--gitea-progress, 0%);
	height: 100%;
	border-radius: var(--radius-s);
	background-color: var(--interactive-accent);
}

.gitea-milestone__stats {
	display: flex;
	flex-wrap: wrap;
	gap: var(--size-4-3);
	margin-top: var(--size-4-1);
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
}

/* Dependency graph (issue #39) — a DAG of issue nodes drawn as an SVG. The SVG
 * carries only geometry; every colour/weight is a CSS class driven by Obsidian
 * variables, mirroring the card/chip state vocabulary (open green, closed red,
 * in-progress orange). The block scrolls horizontally if the graph is wider than
 * the note, and the SVG scales down to fit. */
.gitea-graph {
	position: relative;
	overflow-x: auto;
}

.gitea-graph__stale-badge {
	display: inline-block;
	margin-bottom: var(--size-4-2);
}

/* Graph header (issue #42) — the scope title on the left, a "Refresh" button on
   the right that forces a fresh fetch on demand, matching the search toolbar. */
.gitea-graph__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--size-4-2);
	margin-bottom: var(--size-4-2);
}

/* Title/subtitle stack — sized down to match the graph node text so the header
   reads as a quiet caption, not a banner (#44): the title mirrors the node
   number (Issue #) and the subtitle mirrors the node title (Description). */
.gitea-graph__heading {
	display: flex;
	flex-direction: column;
}

.gitea-graph__title {
	font-size: var(--font-ui-small);
	font-weight: var(--font-medium);
	color: var(--text-normal);
}

.gitea-graph__subtitle {
	font-size: var(--font-ui-smaller);
	color: var(--text-muted);
}

/* Header links (issue #47) — the title opens the repo and each milestone opens
   its page in Gitea. Keep the quiet caption colour so the header still reads as a
   caption, not a banner; only the hover underline signals they are clickable. */
a.gitea-graph__title,
.gitea-graph__milestone-link {
	color: inherit;
	text-decoration: none;
}

a.gitea-graph__title:hover,
.gitea-graph__milestone-link:hover {
	cursor: pointer;
	text-decoration: underline;
}

.gitea-graph__svg {
	max-width: 100%;
	height: auto;
}

.gitea-graph__svg text {
	font-family: var(--font-interface);
}

/* Edges — blocker → dependent, with the arrowhead marker below. */
.gitea-graph__edge {
	fill: none;
	stroke: var(--text-muted);
	stroke-width: 1.5px;
}

.gitea-graph__arrow {
	fill: var(--text-muted);
}

/* Nodes — an SVG anchor opening the issue in Gitea. */
.gitea-graph__node {
	cursor: pointer;
}

.gitea-graph__node-rect {
	fill: var(--background-secondary);
	stroke: var(--background-modifier-border);
	stroke-width: 1.5px;
}

.gitea-graph__node:hover .gitea-graph__node-rect {
	fill: var(--background-modifier-hover);
}

/* State colours the node outline, matching the dot/chip palette. */
.gitea-graph__node--open .gitea-graph__node-rect {
	stroke: var(--color-green);
}

.gitea-graph__node--closed .gitea-graph__node-rect {
	stroke: var(--color-red);
}

.gitea-graph__node--in-progress .gitea-graph__node-rect {
	stroke: var(--color-orange);
}

/* Closed work recedes; a still-blocked open issue is dimmed with a dashed
 * outline, so the currently-unblocked nodes (what the processor picks up next)
 * read as the live front. */
.gitea-graph__node--closed {
	opacity: 0.7;
}

.gitea-graph__node--blocked {
	opacity: 0.5;
}

.gitea-graph__node--blocked .gitea-graph__node-rect {
	stroke-dasharray: 4 3;
}

/* State dot inside each node, same palette as the cards/table. */
.gitea-graph__node-dot {
	fill: var(--text-muted);
}

.gitea-graph__node-dot--open {
	fill: var(--color-green);
}

.gitea-graph__node-dot--closed {
	fill: var(--color-red);
}

.gitea-graph__node-dot--in-progress {
	fill: var(--color-orange);
}

.gitea-graph__node-number {
	fill: var(--text-normal);
	font-weight: var(--font-semibold);
	font-size: var(--font-ui-small);
	font-variant-numeric: tabular-nums;
}

.gitea-graph__node-title {
	fill: var(--text-muted);
	font-size: var(--font-ui-smaller);
}

/* Line 5 — on-card quick actions (comment / toggle state / labels) */
.gitea-card__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--size-4-2);
	margin-top: var(--size-4-2);
}

.gitea-card__action {
	padding: var(--size-4-1) var(--size-4-2);
	font-size: var(--font-ui-smaller);
}

/* Refresh sits at the far end of the bar, away from the write actions */
.gitea-card__action--refresh {
	order: 1;
	margin-left: auto;
}

/* Shared manual-refresh control (issue #45) — one small, subtle ghost icon
   used by the single-issue card, the search toolbar, and the graph header so
   "refresh now" reads identically everywhere and stays out of the way until
   hovered. Builds on Obsidian's clickable-icon, matching the settings-tab
   refresh buttons. */
.gitea-refresh-button {
	color: var(--text-muted);
	--icon-size: var(--icon-s);
}

.gitea-refresh-button:hover {
	color: var(--text-normal);
}

/* Corner placement (issue #45) — the search and graph blocks pin their refresh
   to the bottom-right corner so every "refresh now" affordance lives in the
   same out-of-the-way spot, over the block rather than in a top toolbar. */
.gitea-refresh-button--corner {
	position: absolute;
	right: var(--size-4-2);
	bottom: var(--size-4-2);
	z-index: 1;
}

/* Spin the icon while a refresh is in flight (issue #45) — the click adds this
   class and it spins until the refreshed block tears the button down. */
.gitea-refresh-button--spinning svg {
	animation: gitea-refresh-spin 0.8s linear infinite;
}

@keyframes gitea-refresh-spin {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.gitea-refresh-button--spinning svg {
		animation: none;
	}
}

/* Inline comment box, revealed under the action bar */
.gitea-card__comment-form {
	display: flex;
	flex-direction: column;
	gap: var(--size-4-2);
	flex-basis: 100%;
	margin-top: var(--size-4-1);
}

.gitea-card__comment-form--hidden {
	display: none;
}

.gitea-card__comment-input {
	width: 100%;
	resize: vertical;
	font-family: var(--font-text);
}

.gitea-card__comment-buttons {
	display: flex;
	gap: var(--size-4-2);
	align-items: center;
	flex-wrap: wrap;
}

/* Image-attach picker in the comment box (issue #56), shown only when "Show images
 * in comments" is on. Pushed to the right so it trails the Send/Cancel buttons, and
 * shrunk to the small UI scale so it sits inline without dominating the row. */
.gitea-card__comment-file {
	margin-left: auto;
	font-size: var(--font-ui-smaller);
	max-width: 100%;
}

/* Comment-thread preview (issue #40) — the comment count on a single-issue card
 * becomes a toggle button that expands a list of the latest comments inline. The
 * button is reset to look like the plain count it replaces, with a hover/caret
 * affordance to signal it is clickable. */
.gitea-card__comments--toggle {
	border: none;
	box-shadow: none;
	padding: 0;
	margin: 0;
	height: auto;
	background-color: transparent;
	color: var(--text-muted);
	font-size: inherit;
	line-height: inherit;
	cursor: pointer;
}

.gitea-card__comments--toggle:hover {
	color: var(--text-normal);
}

.gitea-card__comments-caret {
	font-size: 0.85em;
}

/* The expanded thread sits between the status line and the action bar. */
.gitea-card__comments-thread {
	display: flex;
	flex-direction: column;
	gap: var(--size-4-2);
	margin-top: var(--size-4-2);
	padding-top: var(--size-4-2);
	border-top: 1px solid var(--background-modifier-border);
}

/* Loading / empty / stale / "older hidden" one-liners inside the thread. */
.gitea-card__comments-loading,
.gitea-card__comments-message {
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
}

.gitea-card__comment-header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--size-4-1);
	font-size: var(--font-ui-smaller);
}

.gitea-card__comment-author {
	font-weight: var(--font-medium);
	color: var(--text-normal);
}

.gitea-card__comment-time {
	color: var(--text-muted);
}

/* Rendered Markdown body — kept compact; trim the outer margins Obsidian's
 * Markdown renderer adds to the first/last block so comments stack tightly. */
.gitea-card__comment-body {
	margin-top: var(--size-4-1);
	font-size: var(--font-ui-small);
}

.gitea-card__comment-body > :first-child {
	margin-top: 0;
}

.gitea-card__comment-body > :last-child {
	margin-bottom: 0;
}

/* Images pasted into Gitea comments (issue #53), shown only when the
 * "Show images in comments" setting is on. Sized by CSS (community rule —
 * no inline styles): never wider than the card, capped height. */
.gitea-card__comment-image {
	display: block;
	max-width: 100%;
	height: auto;
	max-height: 320px;
	margin: var(--size-4-2) 0;
	border-radius: var(--radius-s);
}

/* While the authed bytes are in flight the native src is blanked, so show a
 * dashed placeholder box in its place. */
.gitea-card__comment-image--loading {
	min-width: 64px;
	min-height: 48px;
	background-color: var(--background-secondary);
	border: 1px dashed var(--background-modifier-border);
}

/* A loaded image is clickable — opens the in-app lightbox. */
.gitea-card__comment-image--loaded {
	cursor: zoom-in;
}

/* Shown in place of an image our token couldn't fetch (CF-Access reject /
 * invalid token), carrying the auth-taxonomy message. */
.gitea-card__comment-image-error {
	display: inline-block;
	padding: 0 var(--size-4-1);
	border-radius: var(--radius-s);
	background-color: var(--background-secondary);
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
}

/* Attachment strip (issue #54) — a wrapping row of image thumbnails and file
 * chips under a single-issue card's body, shown only when "Show attachments" is
 * on. Sized entirely in CSS (community rule — no inline styles). */
.gitea-card__attachments {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--size-4-2);
	margin-top: var(--size-4-2);
}

/* Image attachment thumbnail — a small fixed-height preview; click opens the
 * shared lightbox (the --loaded state below adds the zoom cursor). */
.gitea-card__attachment-thumb {
	height: 64px;
	width: auto;
	max-width: 96px;
	object-fit: cover;
	border-radius: var(--radius-s);
	border: 1px solid var(--background-modifier-border);
}

/* While the authed bytes are in flight there is no src — show a dashed box. */
.gitea-card__attachment-thumb--loading {
	width: 64px;
	background-color: var(--background-secondary);
	border-style: dashed;
}

.gitea-card__attachment-thumb--loaded {
	cursor: zoom-in;
}

/* Non-image attachment — a 📎 filename chip linking to the authed download. */
.gitea-card__attachment-file {
	display: inline-flex;
	align-items: center;
	gap: var(--size-4-1);
	padding: 0 var(--size-4-2);
	border-radius: var(--radius-s);
	background-color: var(--background-modifier-border);
	color: var(--text-normal);
	font-size: var(--font-ui-smaller);
	line-height: 1.6;
	text-decoration: none;
}

.gitea-card__attachment-file:hover {
	background-color: var(--background-modifier-hover);
	text-decoration: none;
}

.gitea-card__attachment-file-name {
	overflow: hidden;
	max-width: 16em;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Shown in place of a thumbnail our token couldn't fetch (CF-Access reject /
 * invalid token), carrying the auth-taxonomy message — mirrors the comment one. */
.gitea-card__attachment-error {
	display: inline-block;
	padding: 0 var(--size-4-1);
	border-radius: var(--radius-s);
	background-color: var(--background-secondary);
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
}

/* In-app lightbox modal for a full-size comment image (issue #53). */
.gitea-lightbox-modal {
	max-width: 90vw;
}

.gitea-lightbox {
	display: flex;
	align-items: center;
	justify-content: center;
}

.gitea-lightbox__image {
	max-width: 100%;
	max-height: 80vh;
	height: auto;
	border-radius: var(--radius-s);
}

.gitea-lightbox__status {
	padding: var(--size-4-4);
	color: var(--text-muted);
}

/* Inline chip — a completed GITEA:owner/repo:#123 reference in rendered prose */
.gitea-chip {
	display: inline-flex;
	align-items: center;
	gap: var(--size-4-1);
	padding: 0 var(--size-4-1);
	border-radius: var(--radius-s);
	background-color: var(--background-modifier-border);
	color: var(--text-normal);
	/* Chips render inline in prose, so size relative to the surrounding text
	 * (em) rather than a fixed UI scale — this keeps them in step with the
	 * note's font size instead of staying small when the reader zooms text. */
	font-size: 0.9em;
	font-variant-numeric: tabular-nums;
	text-decoration: none;
	line-height: 1.5;
}

.gitea-chip:hover {
	background-color: var(--background-modifier-hover);
	text-decoration: none;
}

/* Per-project accent (issue #30): mirror the card's coloured left border on the
 * inline chip, driven by the same --gitea-accent custom property the plugin
 * sets per repo. Chips without a configured accent keep the plain background. */
.gitea-chip--accented {
	border-left: 3px solid var(--gitea-accent, var(--background-modifier-border));
}

.gitea-chip--closed {
	opacity: 0.6;
}

.gitea-chip__dot {
	width: 0.55em;
	height: 0.55em;
	border-radius: 50%;
	background-color: var(--text-muted);
}

.gitea-chip__dot--open {
	background-color: var(--color-green);
}

.gitea-chip__dot--closed {
	background-color: var(--color-red);
}

.gitea-chip__dot--in-progress {
	background-color: var(--color-orange);
}

/* Issue title, shown once the issue loads — truncated so a long title can't
   blow out the line it sits in. */
.gitea-chip__title {
	overflow: hidden;
	max-width: 24em;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Open/closed status badge, mirroring the full card's state pill. */
.gitea-chip__state {
	padding: 0 var(--size-4-1);
	border-radius: var(--radius-s);
	background-color: var(--background-modifier-border);
	color: var(--text-muted);
	/* Relative to the chip (em) so it tracks the surrounding text too. */
	font-size: 0.85em;
	font-weight: var(--font-semibold);
	letter-spacing: 0.02em;
	text-transform: uppercase;
	/* Intra-token break lock lives in the shared theme-proof rule below. */
}

.gitea-chip__state--open {
	background-color: var(--color-green);
	color: var(--text-on-accent);
}

.gitea-chip__state--closed {
	background-color: var(--color-red);
	color: var(--text-on-accent);
}

.gitea-chip__state--in-progress {
	background-color: var(--color-orange);
	color: var(--text-on-accent);
}

/* Keep the placeholder chip compact (just the dot + number) before the issue
   has loaded — empty title/state slots add no width or stray padding. */
.gitea-chip__title:empty,
.gitea-chip__state:empty {
	display: none;
}

/* Inline autocomplete suggestions (EditorSuggest dropdown) */
.gitea-suggestion {
	display: flex;
	align-items: baseline;
	gap: var(--size-4-2);
}

.gitea-suggestion__number {
	flex-shrink: 0;
	font-weight: var(--font-semibold);
	font-variant-numeric: tabular-nums;
}

.gitea-suggestion__title {
	color: var(--text-muted);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* New-issue / convert-selection modal */
.gitea-new-issue__body {
	width: 100%;
	resize: vertical;
	font-family: var(--font-text);
}

/* Toggleable label chips. The grid wraps and is height-capped + scrollable, so
 * a repo with many labels never grows the modal unbounded. */
.gitea-new-issue__labels {
	display: flex;
	flex-wrap: wrap;
	gap: var(--size-4-1);
	max-height: 12em;
	overflow-y: auto;
	padding: var(--size-4-1) 0;
}

/* Unselected chip: outlined in the label's colour. Tapping fills it in. */
.gitea-new-issue__label {
	height: auto;
	padding: var(--size-4-1) var(--size-4-2);
	border: 1px solid var(--gitea-label-bg, var(--background-modifier-border));
	border-radius: var(--radius-s);
	background-color: transparent;
	box-shadow: none;
	color: var(--text-muted);
	font-size: var(--font-ui-smaller);
	line-height: 1.4;
	cursor: pointer;
}

.gitea-new-issue__label.is-selected {
	background-color: var(--gitea-label-bg, var(--background-modifier-border));
	color: var(--gitea-label-fg, var(--text-normal));
}

/*
 * Remove affordance on a selected milestone chip in the graph wizard (issue #43):
 * the chip is a dropdown-added member of the set, clicked to drop it back out.
 */
.gitea-new-issue__label-remove {
	margin-inline-start: var(--size-4-1);
	opacity: 0.7;
}

.gitea-new-issue__notice {
	padding: var(--size-4-2) 0;
	color: var(--text-muted);
	font-size: var(--font-ui-small);
}

/* Image picker (issue #57) — file input plus a wrapping grid of thumbnail
 * previews of the queued-but-not-yet-uploaded images. */
.gitea-new-issue__file {
	margin: var(--size-4-1) 0;
}

.gitea-new-issue__previews {
	display: flex;
	flex-wrap: wrap;
	gap: var(--size-4-2);
	padding: var(--size-4-1) 0;
}

/* One preview: the thumbnail with a remove affordance pinned to its corner. */
.gitea-new-issue__preview {
	position: relative;
}

.gitea-new-issue__preview-img {
	height: 64px;
	width: auto;
	max-width: 96px;
	object-fit: cover;
	border-radius: var(--radius-s);
	border: 1px solid var(--background-modifier-border);
}

.gitea-new-issue__preview-remove {
	position: absolute;
	top: calc(-1 * var(--size-4-1));
	inset-inline-end: calc(-1 * var(--size-4-1));
	height: 20px;
	width: 20px;
	padding: 0;
	border-radius: 50%;
	line-height: 1;
	cursor: pointer;
}

/* Insert-existing-issue modal */
.gitea-insert-issue__notice {
	padding: var(--size-4-2) 0;
	color: var(--text-muted);
	font-size: var(--font-ui-small);
}

/* Search-query wizard (issue #34) */
.gitea-search-wizard__notice {
	padding: var(--size-4-2) 0;
	color: var(--text-muted);
	font-size: var(--font-ui-small);
}

/* Live preview of the generated block — read-only, monospace, wraps long lines. */
.gitea-search-wizard__preview {
	margin: 0 0 var(--size-4-2);
	padding: var(--size-4-2);
	border: 1px solid var(--background-modifier-border);
	border-radius: var(--radius-s);
	background-color: var(--background-secondary);
	color: var(--text-normal);
	font-family: var(--font-monospace);
	font-size: var(--font-ui-smaller);
	white-space: pre-wrap;
	word-break: break-word;
}

/* Theme-proof intra-token lock (issues #21, #28, #59) — issue numbers (#123) and
 * state badges (OPEN / CLOSED / STALE) are indivisible tokens that must never
 * split mid-token (CLOS / ED), even under mobile themes that pill them and reset
 * the break behaviour with multi-class selectors. Each class is repeated three
 * times to raise specificity to (0,3,0) — no importance flag (the community
 * linter rejects it), yet above any realistic theme selector on these spans.
 * keep-all guards against themes that set word-break: break-all globally. */
.gitea-card__stale-badge.gitea-card__stale-badge.gitea-card__stale-badge,
.gitea-card__number.gitea-card__number.gitea-card__number,
.gitea-card__state.gitea-card__state.gitea-card__state,
.gitea-search-table__number.gitea-search-table__number.gitea-search-table__number,
.gitea-search-table__state.gitea-search-table__state.gitea-search-table__state,
.gitea-chip__state.gitea-chip__state.gitea-chip__state {
	white-space: nowrap;
	word-break: keep-all;
	overflow-wrap: normal;
}

/* Mobile (issue #28) — Obsidian sets body.is-mobile on phones. Tighten the
 * inter-item gaps in the meta/status rows so the now-unbreakable badges have a
 * little more room to sit on one line before the row wraps between them.
 * Desktop rendering is untouched. */
body.is-mobile .gitea-card__meta,
body.is-mobile .gitea-card__status {
	gap: var(--size-4-1);
}

/* Mobile search table (issue #59) — phone Obsidian themes routinely restyle plain
 * <table>s for small screens: they float each row into a spaced card, inflate cell
 * padding, override our intra-token break rules, and let the table grow past the
 * viewport. On the compact search table that reads as the reported breakage — big
 * gaps between rows, the issue number wrapping (#5 / 6), and the title + state badge
 * spilling off the right edge. Desktop is perfect because desktop themes leave
 * tables alone, so this repair is scoped to body.is-mobile and forces the table back
 * to a tight, fixed-width grid. The resets repeat each class three times on
 * purpose (the same theme-proofing rationale as the intra-token lock above):
 * with body.is-mobile that lands at (0,4,1) specificity, so a hostile mobile
 * theme's `td`/`tr`/`table` rules can't out-specify ours — no importance flag
 * needed (the community linter rejects it). */
body.is-mobile .gitea-search-table.gitea-search-table.gitea-search-table {
	/* table-layout: fixed pins the table to the container width so it can never
	 * overflow the viewport; the title column then absorbs the slack and truncates
	 * with its existing ellipsis instead of pushing the row off-screen. */
	display: table;
	table-layout: fixed;
	width: 100%;
	margin: 0;
}

body.is-mobile .gitea-search-table.gitea-search-table.gitea-search-table tbody {
	display: table-row-group;
}

/* Undo themes that turn each row into a spaced, padded card — the source of the
 * "weird spacing" between rows. */
body.is-mobile .gitea-search-table__row.gitea-search-table__row.gitea-search-table__row {
	display: table-row;
	margin: 0;
	padding: 0;
	background-color: transparent;
	border-radius: 0;
}

body.is-mobile .gitea-search-table__cell.gitea-search-table__cell.gitea-search-table__cell {
	display: table-cell;
	padding: var(--size-4-1);
	vertical-align: middle;
}

/* The state dot already encodes open/closed/in-progress, so the text badge is
 * redundant on a narrow phone — and it, plus the cross-repo owner/repo column, were
 * the cells overflowing off the right edge. Drop both on mobile so the number and
 * title own the row; the linked number still taps through to the full issue. */
body.is-mobile .gitea-search-table__cell--state.gitea-search-table__cell--state.gitea-search-table__cell--state,
body.is-mobile .gitea-search-table__cell--repo.gitea-search-table__cell--repo.gitea-search-table__cell--repo {
	display: none;
}

/* With table-layout: fixed the dot and number need explicit columns: the dot a
 * snug fixed width, the number wide enough for "#999" so it never wraps to #9 / 9. */
body.is-mobile .gitea-search-table__cell--dot.gitea-search-table__cell--dot.gitea-search-table__cell--dot {
	width: 1.4em;
}

body.is-mobile .gitea-search-table__cell--number.gitea-search-table__cell--number.gitea-search-table__cell--number {
	width: 3.2em;
}
