Files
Obsidian-Vault-2026/.obsidian/plugins/gitea-cards/styles.css
T
2026-07-23 14:20:36 -04:00

1200 lines
32 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Gitea Cards — styles
*
* Card, chip, and badge rules are added by the feature tickets (F1F8).
* 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;
}