/* Typography (T-004, D-013). @imports must stay first in the assembled theme. */
@import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&family=Fira+Mono:wght@400;700&display=swap");

@font-face {
  font-family: "Ark Pixel 12 Monospace SC";
  src: url("/assets/soppy/ark-pixel-12px-monospaced-zh_cn.ttf.woff2") format("woff2");
  font-display: swap;
}

:root {
  /* Overrides base.css:3. The zh_cn build covers CJK; anything it lacks falls through the
     system stack and, via --fonts-regular (base.css:64), to --fonts-emoji. Accepted
     tradeoff: 16px body is a 1.333x non-integer scale of its 12px design grid. */
  --fonts-proportional: "Ark Pixel 12 Monospace SC", -apple-system, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial;
  /* Fira Code first (coding ligatures), Fira Mono behind it, then the upstream chain
     (base.css:4). Code is the only non-pixel surface — every code context consumes
     --fonts-monospace (base.css:96-101, :430, :652; easymde.css:16, 151; ...). */
  --fonts-monospace: "Fira Code", "Fira Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace, var(--fonts-emoji);
  /* --fonts-emoji keeps base.css:8's dummy value; --fonts-override (base.css:64) is
     deliberately not set here — see the :lang() block below. */
}

body {
  /* Grayscale antialiasing avoids subpixel fringing on bitmap glyph edges (`none`
     distorts the outline woff2, which browsers rasterize at 16px). */
  -webkit-font-smoothing: antialiased;
}

/* font_i18n.css:1-19 points --fonts-override at per-language stacks and --fonts-regular
   (base.css:64) resolves it first, so CJK-locale pages would skip our body face. Mirroring
   those selectors at the same specificity (0,2,0, later file wins) keeps ark-pixel in
   front for every language; upstream's per-language preference is knowingly overridden
   (D-017). */
:root :lang(ja),
:root :lang(zh-CN),
:root :lang(zh-TW),
:root :lang(zh-HK),
:root :lang(ko) {
  --fonts-override: var(--fonts-proportional);
}

gitea-theme-meta-info {
  --theme-display-name: "Soppy Light";
  --theme-color-scheme: "light";
}

/* Palette: pxlkit neutral scheme — LIGHT layering, where elevation gets darker: page
   #eff2f4, chrome/panel #e4e8eb, content/card #d9dee2; borders #bcc4ca / #8C8770; text
   #1A1A2E. Primary = pxlkit indigo #4F46E5, nudged 3pt darker so links clear AA on cards. */

:root {
  --is-dark-theme: false;
  --color-primary: #4a41dc;
  --color-primary-contrast: #ffffff;
  --color-primary-dark-1: #352bd8;
  --color-primary-dark-2: #2d24c1;
  --color-primary-dark-3: #271fa7;
  --color-primary-dark-4: #211a8e;
  --color-primary-dark-5: #1b1574;
  --color-primary-dark-6: #15115a;
  --color-primary-dark-7: #0e0b3c;
  --color-primary-light-1: #5f57e0;
  --color-primary-light-2: #736ce4;
  --color-primary-light-3: #8882e8;
  --color-primary-light-4: #a09bed;
  --color-primary-light-5: #bdbaf2;
  --color-primary-light-6: #d5d3f7;
  --color-primary-light-7: #e6e5fa;
  --color-primary-alpha-10: #4a41dc19;
  --color-primary-alpha-20: #4a41dc33;
  --color-primary-alpha-30: #4a41dc4b;
  --color-primary-alpha-40: #4a41dc66;
  --color-primary-alpha-50: #4a41dc80;
  --color-primary-alpha-60: #4a41dc99;
  --color-primary-alpha-70: #4a41dcb3;
  --color-primary-alpha-80: #4a41dccc;
  --color-primary-alpha-90: #4a41dce1;
  --color-primary-hover: var(--color-primary-dark-1);
  --color-primary-active: var(--color-primary-dark-2);
  --color-secondary: #bebaa2;
  --color-secondary-dark-1: #b0ac95;
  --color-secondary-dark-2: #a29e87;
  --color-secondary-dark-3: #97937c;
  --color-secondary-dark-4: #8c8770;
  --color-secondary-dark-5: #7e7a66;
  --color-secondary-dark-6: #706c59;
  --color-secondary-dark-7: #625e4c;
  --color-secondary-dark-8: #54503f;
  --color-secondary-dark-9: #464232;
  --color-secondary-dark-10: #383425;
  --color-secondary-dark-11: #2a271a;
  --color-secondary-dark-12: #1e1c14;
  --color-secondary-dark-13: #131118;
  --color-secondary-light-1: #c9c6b2;
  --color-secondary-light-2: #d4d1c1;
  --color-secondary-light-3: #dedbcf;
  --color-secondary-light-4: #e8e5dc;
  --color-secondary-alpha-10: #bebaa219;
  --color-secondary-alpha-20: #bebaa233;
  --color-secondary-alpha-30: #bebaa24b;
  --color-secondary-alpha-40: #bebaa266;
  --color-secondary-alpha-50: #bebaa280;
  --color-secondary-alpha-60: #bebaa299;
  --color-secondary-alpha-70: #bebaa2b3;
  --color-secondary-alpha-80: #bebaa2cc;
  --color-secondary-alpha-90: #bebaa2e1;
  --color-secondary-button: var(--color-secondary-dark-4);
  --color-secondary-hover: var(--color-secondary-dark-5);
  --color-secondary-active: var(--color-secondary-dark-6);
  /* console colors - used for actions console and console files */
  --color-console-fg: #1a1a2e;
  --color-console-fg-subtle: #4a4a5f;
  --color-console-bg: #c4cbd0;
  --color-console-hover-bg: #d0d6da;
  --color-console-active-bg: #bcc4ca;
  --color-console-link: #4a4a5f;
  /* named colors */
  --color-red: #c83741;
  --color-orange: #c96a15;
  --color-yellow: #fbbf24;
  --color-olive: #7f9418;
  --color-green: #008c4b;
  --color-teal: #24827a;
  --color-blue: #2c6cb8;
  --color-violet: #683ed6;
  --color-purple: #8237c8;
  --color-pink: #c84678;
  --color-brown: #79553a;
  --color-black: #1a1a2e;
  /* light variants - produced via Sass scale-color(color, $lightness: +25%) */
  --color-red-light: #e39ba0;
  --color-orange-light: #e89354;
  --color-yellow-light: #fde4a1;
  --color-olive-light: #adc23f;
  --color-green-light: #0dff8e;
  --color-teal-light: #55d0c6;
  --color-blue-light: #5f96d8;
  --color-violet-light: #baa7ec;
  --color-purple-light: #c19be3;
  --color-pink-light: #e5a8c0;
  --color-brown-light: #a47b5b;
  --color-black-light: #48487f;
  /* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */
  --color-red-dark-1: #a02c34;
  --color-orange-dark-1: #b55f13;
  --color-yellow-dark-1: #e8a804;
  --color-olive-dark-1: #728515;
  --color-green-dark-1: #005930;
  --color-teal-dark-1: #195a55;
  --color-blue-dark-1: #2761a6;
  --color-violet-dark-1: #5027ba;
  --color-purple-dark-1: #682ca0;
  --color-pink-dark-1: #a93260;
  --color-brown-dark-1: #6d4c34;
  --color-black-dark-1: #08080d;
  /* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */
  --color-red-dark-2: #782127;
  --color-orange-dark-2: #a05211;
  --color-yellow-dark-2: #b68403;
  --color-olive-dark-2: #657613;
  --color-green-dark-2: #002614;
  --color-teal-dark-2: #0e322f;
  --color-blue-dark-2: #225694;
  --color-violet-dark-2: #3e1e90;
  --color-purple-dark-2: #4e2178;
  --color-pink-dark-2: #822749;
  --color-brown-dark-2: #61432e;
  --color-black-dark-2: #000000;
  /* ansi colors used for actions console and console files */
  --color-ansi-black: #1a1a2e;
  --color-ansi-red: #c83741;
  --color-ansi-green: #008c4b;
  --color-ansi-yellow: #b48700;
  --color-ansi-blue: #4f46e5;
  --color-ansi-magenta: #c84678;
  --color-ansi-cyan: #24827a;
  --color-ansi-white: var(--color-console-fg-subtle);
  --color-ansi-bright-black: #4a4a66;
  --color-ansi-bright-red: #dc7f85;
  --color-ansi-bright-green: #00e87c;
  --color-ansi-bright-yellow: #ffc311;
  --color-ansi-bright-blue: #9c96f0;
  --color-ansi-bright-magenta: #dd8dac;
  --color-ansi-bright-cyan: #39c8bc;
  --color-ansi-bright-white: var(--color-console-fg);
  /* 16-color series */
  --color-series-16-0: #6f9c2e;
  --color-series-16-1: #3c8527;
  --color-series-16-2: #c14e58;
  --color-series-16-3: #8a8a1f;
  --color-series-16-4: #a83aa0;
  --color-series-16-5: #7445e9;
  --color-series-16-6: #c67d28;
  --color-series-16-7: #3fa88a;
  --color-series-16-8: #aa4d30;
  --color-series-16-9: #2a6f84;
  --color-series-16-10: #c45327;
  --color-series-16-11: #3d965c;
  --color-series-16-12: #792a93;
  --color-series-16-13: #439d73;
  --color-series-16-14: #274ea8;
  --color-series-16-15: #982e85;
  /* other colors */
  --color-grey: #646478;
  --color-grey-light: #8a8a9e;
  --color-gold: #b48700;
  --color-white: #ffffff;
  --color-diff-added-fg: #1e6b2e;
  --color-diff-added-linenum-bg: #dcf3da;
  --color-diff-added-row-bg: #eef7ea;
  --color-diff-added-row-border: #eef7ea;
  --color-diff-added-word-bg: #c6e6bd;
  --color-diff-moved-row-bg: #f0f2d8;
  --color-diff-moved-row-border: #d6dd9a;
  --color-diff-removed-fg: #a52a1f;
  --color-diff-removed-linenum-bg: #f6dcd7;
  --color-diff-removed-row-bg: #faf0ec;
  --color-diff-removed-row-border: #faf0ec;
  --color-diff-removed-word-bg: #f2c4bb;
  --color-diff-inactive: #e1e6e9;
  --color-error-border: #c8374166;
  --color-error-bg: #f7dedf;
  --color-error-bg-active: #eec6c8;
  --color-error-bg-hover: #f3d2d4;
  --color-error-text: #a82a32;
  --color-success-border: #008c4b66;
  --color-success-bg: #dcefe1;
  --color-success-text: #00693c;
  --color-warning-border: #b4870066;
  --color-warning-bg: #f3e9ce;
  --color-warning-text: #7a5c00;
  --color-info-border: #24827a66;
  --color-info-bg: #d9edeb;
  --color-info-text: #16574f;
  --color-priority-border: #8237c866;
  --color-priority-bg: #e9def3;
  --color-priority-text: #5b2591;
  --color-red-badge: #93242b;
  --color-red-badge-bg: #93242b1a;
  --color-red-badge-hover-bg: #93242b4d;
  --color-green-badge: #005530;
  --color-green-badge-bg: #0055301a;
  --color-green-badge-hover-bg: #0055304d;
  --color-yellow-badge: #5e4600;
  --color-yellow-badge-bg: #5e46001a;
  --color-yellow-badge-hover-bg: #5e46004d;
  --color-orange-badge: #7a3908;
  --color-orange-badge-bg: #7a39081a;
  --color-orange-badge-hover-bg: #7a39084d;
  --color-git: #f05133;
  --color-logo: #4a41dc;
  /* target-based colors */
  --color-body: #eff2f4;
  --color-box-header: #e4e8eb;
  --color-box-body: #d9dee2;
  --color-box-body-highlight: #e1e6e9;
  --color-text-dark: #1a1a2e;
  --color-text: #232338;
  --color-text-light: #2d2d42;
  --color-text-light-1: #38384e;
  --color-text-light-2: #43435a;
  --color-text-light-3: #4e4e63;
  --color-footer: var(--color-nav-bg);
  --color-timeline: #bcc4ca;
  --color-input-text: var(--color-text-dark);
  --color-input-background: #d0d6da;
  --color-input-toggle-background: #e4e8eb;
  --color-input-border: var(--color-secondary-dark-1);
  --color-light: #1a1a2e0a;
  --color-light-border: #1a1a2e26;
  --color-hover: #1a1a2e10;
  --color-hover-opaque: #dfe4e8; /* TODO: color-mix(in srgb, var(--color-body), var(--color-hover)); */
  --color-active: #1a1a2e1f;
  --color-menu: #d9dee2;
  --color-card: #d9dee2;
  --color-markup-table-row: #1a1a2e0d;
  --color-markup-code-block: #1a1a2e14;
  --color-markup-code-inline: #1a1a2e18;
  --color-button: #e4e8eb;
  --color-code-bg: #d0d6da;
  --color-shadow: #1a1a2e30;
  --color-shadow-opaque: #9aa3ab;
  --color-secondary-bg: #d0d6da;
  --color-expand-button: #d0d6da;
  --color-placeholder-text: var(--color-text-light-3);
  --color-editor-line-highlight: var(--color-secondary-alpha-30);
  --color-editor-selection: var(--color-primary-alpha-30);
  --color-project-column-bg: #e6eaed; /* cool literal: the secondary ladder stays warm */
  --color-caret: var(--color-text-dark);
  --color-reaction-bg: #1a1a2e0d;
  --color-reaction-hover-bg: var(--color-primary-light-5);
  --color-reaction-active-bg: var(--color-primary-light-6);
  --color-tooltip-text: #eff2f4;
  --color-tooltip-bg: #26263c;
  --color-nav-bg: #e4e8eb;
  --color-nav-hover-bg: #dde2e6; /* cool literal: the secondary ladder stays warm */
  --color-nav-text: var(--color-text);
  --color-secondary-nav-bg: #eaedf0;
  --color-label-text: var(--color-text);
  --color-label-bg: #9494a84b;
  --color-label-hover-bg: #9494a8a0;
  --color-label-active-bg: #9494a8ff;
  --color-accent: var(--color-primary-light-1);
  --color-small-accent: var(--color-primary-light-6);
  --color-highlight-fg: #eed200;
  --color-highlight-bg: #f5efc5;
  --color-overlay-backdrop: #1a1a2ecc;
  --color-danger: var(--color-red);
  --color-transparency-grid-light: #f6f8f9;
  --color-transparency-grid-dark: #d9dee2;
  --color-workflow-edge-hover: #8c8770;
  --color-syntax-keyword: #a04a00;
  --color-syntax-bool: #076872;
  --color-syntax-control: #7d5700;
  --color-syntax-name: #785900;
  --color-syntax-type: #ae2368;
  --color-syntax-number: #105ead;
  --color-syntax-operator: #a04a00;
  --color-syntax-regexp: #773dc5;
  --color-syntax-string: #456800;
  --color-syntax-comment: #4a4a5f;
  --color-syntax-invalid: #c00000;
  --color-syntax-link: var(--color-primary);
  --color-syntax-tag: #a04a00;
  --color-syntax-attribute: #6f41c5;
  --color-syntax-property: #2060a0;
  --color-syntax-variable: #944a00;
  --color-syntax-string-special: #7d5700;
  --color-syntax-escape: #785900;
  --color-syntax-entity: #6f41c5;
  --color-syntax-preproc: #2d6a4b;
  --color-syntax-preproc-file: #105ead;
  --color-syntax-decorator: #2d6a4b;
  --color-syntax-namespace: #4a4a5f;
  --color-syntax-name-pseudo: #6f41c5;
  --color-syntax-comment-special: #773dc5;
  --color-syntax-text: inherit;
  --color-syntax-text-alt: #43435a;
  --color-syntax-punctuation: inherit;
  --color-syntax-whitespace: #c0bcae;
  --color-syntax-diff-fg: #1a1a2e;
  --color-syntax-deleted-bg: #fbe4e0;
  --color-syntax-inserted-bg: #e4f3dc;
  --color-syntax-emph: #8b5000;
  --color-syntax-strong: inherit;
  --color-syntax-heading: #7d5700;
  --color-syntax-subheading: #456800;
  --color-syntax-output: #566068;
  --color-syntax-prompt: #944a00;
  --color-syntax-traceback: #c00000;
  --color-syntax-matching-bracket-bg: #0e8a8038;
  --color-syntax-nonmatching-bracket-bg: #b02e2638;
  /* Pixel bevel/shadow contract consumed by components.css (T-005): pixel geometry
     kept (light top-left, dark bottom-right); #ffffff highlight against border-strong
     #8C8770, hard shadow and frame also #8C8770. */
  --soppy-bevel-raised: inset -2px -2px 0 0 #8c8770, inset 2px 2px 0 0 #ffffff;
  --soppy-bevel-pressed: inset 2px 2px 0 0 #8c8770, inset -2px -2px 0 0 #ffffff;
  --soppy-shadow-hard: 4px 4px 0 0 #8c8770;
  --soppy-border-strong: #8c8770;
  /* Text ink for Gitea's colored fills (components.css, "colored fills"). White here:
     this ladder's named colors are dark enough to carry it. */
  --soppy-ink-on-color: #ffffff;
  accent-color: var(--color-accent);
  color-scheme: light;
}

/* soppy — pixel component overrides (T-005): an override layer loaded after the base
   index.css bundle (D-004), so equal-specificity rules win by source order. The palette
   and the --soppy-* tokens (from palette-light/dark.css) are consumed, not defined here;
   fonts.css holds the two faces. --soppy-ink-on-color is the text ink for Gitea's
   colored fills (see the "colored fills" section). */

/* ---- global geometry: zero radii ---- */
:root {
  /* base.css:25-27 defines 4px / 6px / 99999px; every var-driven radius in the
     base bundle (buttons, labels, cards, avatars, ...) resolves through these */
  --border-radius: 0;
  --border-radius-medium: 0;
  --border-radius-full: 0;
}

/* ---- type scale (T-008) — the single place sizes are decided ---- */
/* ONE KNOB: the root font-size, which is also the rem basis for every upstream rem/em
   dimension (padding, control heights, headings) — a UI scale, not a text size. Every size
   below is pinned in rem against it: code 0.875rem (GitHub's 12:14 code:body ratio),
   labels and mini/small buttons 0.75rem (ark-pixel's native grid), body and
   --line-height-code on the 24px grid. Upstream headings keep their own rem/em scale, and
   the weight pins below change no size. Nothing else in this file declares font-size or
   line-height. */
:root {
  /* base.css:16 (20px): code leading, on the 24px grid */
  --line-height-code: 24px;
  /* base.css:32 (14px): checkbox/radio box + its label's line-height
     (checkbox.css:6-7, 22-23, 34-36, 73-74) */
  --checkbox-size: 1rem;
  /* base.css:42 (12px): consumed by label.css:14 and label.css:231, which must match it
     or chips change height */
  --font-size-label: 0.75rem;
}

/* the knob */
html {
  font-size: 16px;
}

/* base.css:75-78 declares `font-size: 14px` on body directly, so a root-only size would
   leave body copy at 14px; restating it as 1rem keeps the root in charge. base.css:81 sets
   line-height 20px — 24px is 1.5 on the 12px grid. */
body {
  font-size: 1rem;
  line-height: 24px;
}

/* base.css:106-108 shrinks code to 0.95em, which would compound with whatever parent it
   sits in (15.2px, off-grid); pinned in rem instead: 0.875rem = 14px, GitHub's code:body
   ratio. */
pre,
code,
samp,
.tw-font-mono {
  font-size: 0.875rem;
}

/* Upstream button sizes are px (button.css:116-120 mini 11px, :126-131 tiny 12px,
   :139-145 small 13px) and would ignore the knob; mini and small are re-derived at
   0.75rem = 12px, tiny is already 12px. Selectors mirror button.css to win by order. */
.ui.ui.ui.ui.mini.button {
  font-size: 0.75rem;
}

.ui.small.buttons .dropdown,
.ui.small.buttons .dropdown .menu > .item,
.ui.small.buttons .button,
.ui.ui.ui.ui.small.button {
  font-size: 0.75rem;
}

/* base.css:648-654 pins these lines to 12px and base.css:668 pins .code-inner with a
   `font:` shorthand — inheritance reaches neither, so the size is restated at the same
   specificity, mirroring upstream's own selector list (D-004: later file wins).
   Deliberately NOT prefixed with .file-view.code-view: that pair exists only on the file
   view (view_file.tmpl:98) and blame (blame.tmpl:32), while a diff is `file-body file-code
   code-diff` (diff/box.tmpl:172) — the prefix left diff lines at 12px on our 24px leading.
   This list also covers search results (searchfile.tmpl:9), blob excerpts and markup code
   previews. */
.lines-num,
.lines-escape,
.lines-code,
.code-inner {
  font-size: 0.875rem;
}

/* ---- anti-smear weight pins ---- */
/* Upstream asks for heavier weights than this single-400 bitmap face has, and the browser
   synthesises them by smearing the outlines. Each pin mirrors the upstream selector so it
   wins by source order (D-004) and names the rule it neutralises. */

/* header.css:10 (medium): .ui.header — section/modal headings and the home hero h1s
   (home.tmpl:7, 16, 24, 34, 42). The raw h1/h2 arm covers the tagline (home.tmpl:10) and
   devtest headings; user-authored .markup headings keep their semibold
   (markup/content.css:73). */
.page-content h1,
.page-content h2,
.ui.header {
  font-weight: var(--font-weight-normal);
}

/* label.css:15 (medium): chips, sized by --font-size-label above */
.ui.label {
  font-weight: var(--font-weight-normal);
}

/* menu.css:89 (medium): side-nav captions ("User Settings", ...). Mirrored at the same
   specificity — a shorter selector cannot beat this rule (0,4,0). */
.ui.menu .header.item,
.ui.vertical.menu .header.item {
  font-weight: var(--font-weight-normal);
}

/* base.css:791-794 (semibold) and menu.css:407 (medium): the active tab of the
   repo/org/explore/auth strips and of .ui.tabular menus. base.css:793 shares its block
   with .resize-for-semibold::before, a measurement helper: untouched, it just reserves
   slack. */
.ui.tabular.menu .active.item,
.ui.secondary.pointing.menu .active.item {
  font-weight: var(--font-weight-normal);
}

/* menu.css:219 (medium): the active item of a nested sub-menu in a vertical menu (e.g.
   the admin side nav's open group) */
.ui.vertical.menu .item .menu .active.item {
  font-weight: var(--font-weight-normal);
}

/* navbar.css:112-121 (bold): count dots/badges; selector mirrors navbar.css:118-121 */
#navbar a.item .notification_count,
#navbar a.item .header-stopwatch-dot,
#navbar .item .navbar-admin-badge {
  font-weight: var(--font-weight-normal);
}

/* ---- geometry: hard-coded radii upstream ignores the vars for ---- */
/* Fomantic remnants use a literal 0.28571429rem (4px) — killed per surface below; the
   selector citations live in the T-005 task log */

/* forms and inputs */
.ui.input > input,
.ui.form input:not([type="checkbox"], [type="radio"]),
.ui.search > .prompt,
.ui.form textarea,
.ui.icon.input > i.icon,
.ui[class*="left icon"].input > i.icon,
.ui.action.input > .dropdown:first-child,
.ui.action.input > .button:first-child,
.ui.action.input > .dropdown:last-child,
.ui.action.input > .button:last-child {
  border-radius: 0;
}

/* native checkboxes / radios: squares */
input[type="radio"],
input[type="checkbox"] {
  border-radius: 0;
}

/* toggle switch: square track and knob */
.ui.toggle.checkbox label::before,
.ui.toggle.checkbox label::after {
  border-radius: 0;
}

/* segments */
.ui.segment,
.ui.grid.segment,
.ui.segments,
.ui.segments:not(.horizontal) > .segment:first-child,
.ui.segments:not(.horizontal) > .segment:last-child,
.ui.segments:not(.horizontal) > .segment:only-child,
.ui.segments:not(.horizontal) > .segment:has(~ .tw-hidden),
.ui.horizontal.segments,
.ui.horizontal.segments > .segment:first-child,
.ui.horizontal.segments > .segment:last-child,
.ui.attached.segment:last-child,
.ui.attached.segment:has(+ :not(.ui.attached.segment)),
.ui[class*="top attached"].segment,
.ui[class*="top attached"].segment:last-child,
.ui.segment[class*="bottom attached"] {
  border-radius: 0;
}

/* menus */
.ui.menu,
.ui.menu > .item:first-child,
.ui.menu .dropdown.item .menu,
.ui.vertical.menu > .item:first-child,
.ui.vertical.menu > .item:last-child,
.ui.vertical.menu > .active.item:first-child,
.ui.vertical.menu > .active.item:last-child,
.ui.vertical.menu > .active.item:only-child,
.ui.pagination.menu .item:last-child,
.ui.compact.menu .item:last-child,
.ui.compact.menu:not(.secondary) .item:last-child,
.ui.secondary.menu .item,
.ui.secondary.menu .active.item,
.ui.secondary.menu .dropdown.item > .menu,
.ui[class*="top attached"].menu,
.ui.top.attached.menu > .item:first-child {
  border-radius: 0;
}

/* upstream pins these two with !important (menu.css:273 tabular active tab,
   menu.css:367 secondary vertical item) */
.ui.tabular.menu .active.item,
.ui.tabular.menu .active.item:hover,
.ui.secondary.vertical.menu > .item {
  border-radius: 0 !important; /* matches upstream !important in menu.css */
}

/* tables */
.ui.table,
.ui.table > thead > tr:first-child > th:first-child,
.ui.table > thead > tr:first-child > th:last-child,
.ui.table > thead > tr:first-child > th:only-child,
.ui.table > tfoot > tr:first-child > th:first-child,
.ui.table > tfoot > tr:first-child > th:last-child,
.ui[class*="bottom attached"].table {
  border-radius: 0;
}

/* dropdowns */
.ui.dropdown .menu,
.ui.selection.dropdown,
.ui.selection.dropdown .menu,
.ui.upward.dropdown > .menu,
.ui.pointing.dropdown > .menu {
  border-radius: 0;
}

/* upstream pins floating/active/upward selection dropdown radii with !important
   (dropdown.css:318, 630, 635, 730, 734) */
.ui.active.empty.selection.dropdown,
.ui.active.upward.selection.dropdown,
.ui.upward.selection.dropdown.visible,
.ui.floating.dropdown .menu,
.ui.floating.dropdown > .menu {
  border-radius: 0 !important; /* matches upstream !important in dropdown.css */
}

/* misc surfaces */
.ui.top.attached.header,
.ui.search > .results,
.ui.circular.label,
.navbar-left > .item,
.navbar-right > .item,
.navbar-mobile-right > .item,
#navbar a.item .notification_count,
#navbar a.item .header-stopwatch-dot,
#navbar .item .navbar-admin-badge,
.inline-code-block,
.language-stats,
.indicator-dot::after,
.code-editor-container .cm-lint-marker-error,
.code-editor-container .cm-lint-marker-warning,
.EasyMDEContainer .editor-toolbar button {
  border-radius: 0;
}

/* the two spinner literals (dropdown.css:553, 568) keep their own round radius; a spinner
   that reads --border-radius-full above is squared, like the rest of the geometry */

/* ---- buttons ---- */
/* MC-style bevel: lit top/left edge, shaded bottom/right. Upstream hover/active only swap
   background/color vars, so the bevel survives state changes (button.css:30-47, 160-177,
   183-198, 216-275) */
.ui.button,
::file-selector-button {
  border-color: var(--soppy-border-strong);
  box-shadow: var(--soppy-bevel-raised);
}

/* pressed bevel: edges flip */
.ui.button:active,
.ui.active.button,
::file-selector-button:active {
  box-shadow: var(--soppy-bevel-pressed);
}

/* upstream deliberately flattens this floating mini button with !important
   (review.css:10) — left alone on purpose */

/* ---- labels ---- */
/* upstream .ui.label has border-width 0 (label.css:16). Specificity stays at
   .ui.label:not(.scope-parent) so the colored variants (label.css:69+) and hover states
   keep overriding border-color; scope-parent is excluded or the composite two-tone label
   gets a rectangle drawn around it */
.ui.label:not(.scope-parent) {
  border-width: 1px;
  border-color: var(--color-secondary);
}

/* ---- colored fills: Gitea hardcodes white text on them ---- */
/* Every solid .ui.<color>.label and .ui.<color>.button paints its text with
   `color: var(--color-white)` (label.css:90-182, button.css:216-268), as do the Actions
   status badges (actions.css:9-28). On the dark ladder's bright named colors that puts
   white text between 1.34:1 (green — the Open issue badge, view_title.tmpl:50) and
   3.96:1 (purple — Merged), below AA. --soppy-ink-on-color carries the flip.
   Hover is listed because upstream re-declares the color there (label.css:95-98) at
   (0,4,1), which outranks a rest-state (0,4,0) rule. The .basic variants keep their
   colored text: .ui.ui.ui.basic.<color>.label and .ui.basic.<color>.button are more
   specific than anything here. */
.ui.ui.ui.red.label,
.ui.ui.ui.orange.label,
.ui.ui.ui.yellow.label,
.ui.ui.ui.green.label,
.ui.ui.ui.purple.label,
a.ui.ui.ui.red.label:hover,
a.ui.ui.ui.orange.label:hover,
a.ui.ui.ui.yellow.label:hover,
a.ui.ui.ui.green.label:hover,
a.ui.ui.ui.purple.label:hover,
.ui.red.button,
.ui.red.buttons .button,
.ui.green.button,
.runner-container .task-status-success,
.runner-container .task-status-failure,
.runner-container .task-status-running,
.runner-container .task-status-cancelled,
.runner-container .task-status-blocked {
  color: var(--soppy-ink-on-color);
}

/* ---- dashboard activity feed: keycap badge ---- */
/* #activity-feed exists in exactly one template (feeds.tmpl:1, dashboard feed), so the
   ID scoping is what keeps this off the other `.item-trailing` users (42 more occurrences
   across 30 templates) — settings, danger zone, org/team, package pages — where the slot
   wraps real buttons and must keep flex-list.css:62-69's end alignment. In the feed the
   slot holds one decorative 32px action octicon (feeds.tmpl:125-127), so it becomes a
   static keycap: 28px square, raised-bevel texture, content centred, border-box per
   normalize.css:24-28. The size and the svg arithmetic below must stay in step.
   No hover/active rules are authored and none exist upstream for this element
   (flex-list.css:58 only touches anchors). No hard drop shadow on purpose:
   --soppy-shadow-hard is reserved for the floating surfaces, and a 4px offset repeated
   down every feed row would read as noise. */
#activity-feed .item-trailing {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--soppy-border-strong);
  background: var(--color-button);
  box-shadow: var(--soppy-bevel-raised);
}

/* the octicon is a 32px svg from the template (feeds.tmpl:126). width/height:100% fills
   the bordered content box and the 4px padding insets it: 28 - 2*1px border - 2*4px
   padding = 18px for the glyph, 4px on each side. Relies on the global
   box-sizing:border-box (normalize.css:24-28); display:block kills the baseline gap. */
#activity-feed .item-trailing > svg {
  display: block;
  width: 100%;
  height: 100%;
  /* the template's tw-mr-1 (feeds.tmpl:126) would push the glyph off-centre, and it
     needs !important: tailwind.config.ts:27 compiles utilities with `important: true` */
  margin-right: 0 !important;
  padding: 4px;
}

/* ---- inputs ---- */
/* focus gets a 1px inset ring on top of the upstream primary border
   (input.css:29-31) — reads as a chunky 2px pixel frame */
.ui.input > input:focus,
.ui.form input:not([type="checkbox"], [type="radio"]):focus,
.ui.search > .prompt:focus,
.ui.form textarea:focus {
  box-shadow: inset 0 0 0 1px var(--color-primary);
}

/* ---- navbar ---- */
#navbar {
  border-bottom-color: var(--soppy-border-strong);
}

/* active item: pressed-bevel look */
#navbar .item.active {
  box-shadow: var(--soppy-bevel-pressed);
}

/* ---- elevation: soft shadows become the hard offset shadow token ---- */
.ui.dropdown .menu,
.ui.selection.active.dropdown .menu,
.ui.selection.dropdown:focus .menu,
.ui.selection.active.dropdown:hover .menu,
.ui.menu .dropdown.item .menu,
.ui.upward.dropdown > .menu,
.ui.upward.selection.dropdown .menu,
.ui.modal,
.toastify,
.cm-command-palette,
text-expander .suggestions,
.tribute-container,
overflow-menu .overflow-menu-popup,
.ui.search > .results,
.tippy-box[data-theme="default"],
.tippy-box[data-theme="bare"],
.tippy-box[data-theme="menu"],
.tippy-box[data-theme="box-with-header"] {
  box-shadow: var(--soppy-shadow-hard);
}

/* closed-dropdown focus/hover glows: replaced by the border-color signal */
.ui.selection.active.dropdown,
.ui.selection.active.dropdown:hover,
.ui.upward.selection.dropdown.visible,
.ui.upward.active.selection.dropdown:hover {
  box-shadow: none;
}

/* upstream pins the floating menu shadow with !important (dropdown.css:729) */
.ui.floating.dropdown .menu,
.ui.floating.dropdown > .menu {
  box-shadow: var(--soppy-shadow-hard) !important; /* matches dropdown.css:729 */
}

/* toggle knob: raised bevel instead of upstream's 1px 1px 4px soft shadow
   (checkbox.css:143), proportionate to the 18px knob */
.ui.toggle.checkbox label::after {
  box-shadow: var(--soppy-bevel-raised);
}

/* migrate cards: upstream pins rest (none) and hover (soft) shadows with !important
   (repo.css:1648, 1657); scaling disabled too — instant state changes only */
.migrate-entry:hover {
  transform: none;
  box-shadow: var(--soppy-shadow-hard) !important; /* matches repo.css:1657 */
}

/* ---- focus and selection ---- */
/* chunkier keyboard ring, still inset so it cannot clip in overflow containers
   (upstream: 2px / -2px, base.css:315-320) */
a:focus-visible,
button:focus-visible,
.ui.button:focus-visible,
[role="button"]:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: -3px;
}

/* primary fill instead of upstream primary-light-1 + white (base.css:253-256);
   both variants resolve contrast through the palette vars */
::selection,
relative-time::part(root)::selection {
  background: var(--color-primary);
  color: var(--color-primary-contrast);
}

/* ---- home hero ---- */
/* .page-content.home img.logo is the landing-page logo img (home.tmpl:5, 220x220 attrs,
   max-width 220px via home.css:1-3); the header logo keeps upstream's logo.svg.
   brand.png is 2172x724 (exactly 3:1); 576x192 is 48x16 grid units and keeps that ratio.
   object-fit: contain still degrades cleanly to the square svg where content: url() is
   unsupported (Safari). Margins are one grid unit each side (12px still clears the
   navbar's bottom border). */
.page-content.home img.logo {
  content: url("/assets/soppy/brand.png");
  width: 576px;
  max-width: 100%;
  height: 192px;
  object-fit: contain;
  image-rendering: pixelated;
  margin: 12px 0 12px;
}

/* .page-content.home div.hero is the tagline block on the landing page only
   (templates/home.tmpl:6); the element-qualified div avoids the four h1.hero section
   headers on the same page (home.tmpl:16, 24, 34, 42). The art is 1962x802 with a
   transparent sky; bottom-center placement puts the characters on the ground line under
   the tagline. 384px wide (32 grid units) with a 120px (10-unit) reserved ground band;
   at that width the art renders ~157px tall, so its top ~37px of transparent sky sits
   behind the tagline. Below 768px the art goes full width and the band is 84px.
   Only brand art gets image-rendering: pixelated — avatars and photos are never touched */
.page-content.home div.hero {
  padding-bottom: 120px;
  background-image: url("/assets/soppy/landscape.png");
  background-repeat: no-repeat;
  background-position: center bottom;
  background-size: min(100%, 384px) auto;
  image-rendering: pixelated;
}

@media (max-width: 767.98px) {
  .page-content.home div.hero {
    padding-bottom: 84px;
    background-size: 100% auto;
  }
}

/* ---- landing hero: the tagline wins over the art ---- */
/* The art is painted inside the hero's own box, so it can never reach the logo above it
   — the logo is a sibling (home.tmpl:5) and the hero starts below (home.tmpl:6). It does
   reach the tagline, by a width-dependent amount: landscape.png is 1962x802 and its
   content only starts 20.7% down (first row above 1% alpha at y=166), so at >=768px the
   overlap is transparent sky; below 768px up to ~144px of real artwork sits behind the
   text. The fix is the classic pixel-game one: a hard, 0-blur, 8-direction outline in
   --color-body. Deliberately not a scrim — CSS cannot measure the text box, so a scrim
   tall enough to cover the tagline would slice the characters on mobile — and not extra
   padding, which would have to exceed the art's own height there (~287px). --color-body
   is exactly what the hero is painted on (base.css:84), so the outline disappears where
   no art is behind the text and reads as a cut-out where there is; it flips with the
   palette, so one declaration serves light and dark. Nothing upstream declares
   text-shadow (no hits in web_src/css), so no !important. 4px = one glyph pixel at the
   h2's 4x ark-pixel scale. */
.page-content.home div.hero h1,
.page-content.home div.hero h2 {
  text-shadow:
    -4px -4px 0 var(--color-body),
     0   -4px 0 var(--color-body),
     4px -4px 0 var(--color-body),
    -4px    0 0 var(--color-body),
     4px    0 0 var(--color-body),
    -4px  4px 0 var(--color-body),
     0    4px 0 var(--color-body),
     4px  4px 0 var(--color-body);
}


