/* fremforge theme — overrides Forgejo's default color tokens + typography.
 *
 * Forgejo exposes CSS custom properties for theming (`:root` block); we
 * override the subset that's brand-meaningful and leave the rest at
 * upstream defaults. Source-of-truth color tokens:
 * fremforge/graphics/logo/fremforge-design-system.html.
 *
 * Loaded after the upstream theme by header.tmpl so these win on cascade.
 */

:root {
  /* Typography — Inter for UI body, D-DIN for headings/display, system
   * mono for code (D-DIN replaced Recursive 2026-05-08 and is sans-only,
   * so monospace falls through to the system mono cascade). Loaded by
   * fremforge-fonts.css (immediately before this file).
   *
   * P2-UI-11 (2026-05-16): Forgejo 15.x ships
   *   :root * { --fonts-regular: var(--fonts-override, var(--fonts-proportional)), ... }
   * which over-specifies on every descendant and beats a plain `:root`
   * declaration of `--fonts-regular`. Forgejo built an extension hook
   * for exactly this case: declare `--fonts-override` and Forgejo's own
   * rule consumes it via `var(--fonts-override, ...)`. So we set the
   * override variable here (the right hook) AND keep `--fonts-regular`
   * defined for our own selectors that reference it explicitly. The
   * audit's "missing Inter body font" finding closes via this single
   * line — verified live 2026-05-16 via Playwright getComputedStyle. */
  --fonts-override: 'Inter', system-ui, -apple-system, sans-serif;
  --fonts-regular: 'Inter', system-ui, -apple-system, sans-serif;
  --fonts-display: 'D-DIN', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --fonts-monospace: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;

  /* Brand color tokens (light theme defaults). */
  --forge-green: #468A2D;
  --forge-green-deep: #2F5F1F;
  --forge-green-tint: #E5F0DD;
  --ember: #E8791F;
  --ember-deep: #B85A0F;
  --ember-tint: #FDEDDC;
  --birch: #FAF9F5;
  --anvil: #0F1419;
  --anvil-soft: #1B2128;
  --ink: #14181A;
  --neutral-200: #E8EBED;
  --neutral-300: #D5D8D8;
  --neutral-600: #5C6770;
  --neutral-700: #40474D;

  /* Forgejo theme overrides. Forgejo's upstream theme files
   * (`web_src/css/themes/`) define the --color-* namespace; we
   * override the subset we care about. Anything not overridden falls
   * back to the upstream default. */
  --color-primary: var(--forge-green);
  --color-primary-light-1: #59A338;
  --color-primary-light-2: #6CBC44;
  --color-primary-light-3: #80D650;
  --color-primary-light-4: #A8E47F;
  --color-primary-light-5: var(--forge-green-tint);
  --color-primary-light-6: #F0F7E9;
  --color-primary-light-7: #F8FBF4;
  --color-primary-dark-1: #3C7A26;
  --color-primary-dark-2: var(--forge-green-deep);
  --color-primary-dark-3: #1A3712;
  --color-primary-dark-4: #102108;
  --color-primary-dark-5: #060D03;
  --color-primary-dark-6: #030701;
  --color-primary-dark-7: #000000;
  --color-primary-contrast: #FFFFFF;

  /* `--color-secondary` is Forgejo's structural-divider colour (tab
   * underlines, footer top-rule, .divider, .ui.tabular.menu top/bottom).
   * Earlier set to `--ember` (#E8791F) which painted every divider
   * bright orange — clashed badly with the green brand. Bind to a
   * neutral; ember stays reserved for `--color-warning` only.
   * Light variants are progressively softer (light-3 = near-bg). */
  --color-secondary: var(--neutral-300);
  --color-secondary-dark-1: #B8BCBE;
  --color-secondary-dark-2: var(--neutral-600);
  --color-secondary-light-1: #DEE1E2;
  --color-secondary-light-2: #E8EBED;
  --color-secondary-light-3: #F2F4F4;

  /* `--color-accent` is Forgejo's emphasis colour (active-tab indicator,
   * keyboard-focus rings). Bind to brand green — same family as the
   * primary, slightly lighter so it visually reads as "selected"
   * without clashing on cards. */
  --color-accent: var(--forge-green);
  --color-link: var(--forge-green);
  --color-link-dark-1: var(--forge-green-deep);
  --color-link-dark-2: #1A3712;

  --color-text: var(--ink);
  --color-text-dark: var(--ink);
  --color-text-light: var(--neutral-600);
  --color-text-light-1: #6F7A82;
  --color-text-light-2: #7A8085;
  --color-text-light-3: #8B9095;

  --color-body: var(--birch);
  --color-bg: var(--birch);
  --color-box-body: #FFFFFF;
  --color-box-body-highlight: #F8FBF4;
  --color-box-header: var(--birch);
  --color-card: #FFFFFF;
  --color-light: #EFEEE9;
  --color-light-mimic-enabled: #EFEEE9;

  --color-border: var(--neutral-200);
  --color-border-light: #EFEEE9;
  --color-border-secondary: var(--neutral-300);

  --color-success: var(--forge-green);
  --color-success-bg: var(--forge-green-tint);
  --color-success-border: #A8E47F;
  --color-success-text: var(--forge-green-deep);

  --color-warning: var(--ember);
  --color-warning-bg: var(--ember-tint);
  --color-warning-border: #F2AF6F;
  --color-warning-text: var(--ember-deep);

  --color-error: #DC2626;
  --color-error-bg: #FEE2E2;
  --color-error-border: #FCA5A5;
  --color-error-text: #991B1B;

  --color-info: #2563EB;
  --color-info-bg: #DBEAFE;
  --color-info-border: #93C5FD;
  --color-info-text: #1E40AF;

  /* Diff line backgrounds — Forgejo's defaults are saturated mint/pink
   * (#dcfce7 / #fee2e2). Rebind to softer fremforge-aligned greens and
   * a muted ember-tint warm-red so diff views read with the rest of
   * the brand. Word-level (inline emphasis) is one step darker than
   * row-level so token highlights remain visible. */
  --color-diff-added-row-bg: var(--forge-green-tint);
  --color-diff-added-row-border: #B7DDA0;
  --color-diff-added-word-bg: #B7DDA0;
  --color-diff-removed-row-bg: #FCEAEA;
  --color-diff-removed-row-border: #F3B8B8;
  --color-diff-removed-word-bg: #F3B8B8;

  /* Label / pill chips (issue tags, "Public"/"Private", state badges) —
   * upstream is a flat 50% gray translucent. Bind to a neutral with a
   * faint warm cast so chips read as fremforge surfaces, not generic
   * Material/Gitea. */
  --color-label-bg: #EAE7DE;
  --color-label-hover-bg: #DFDBCF;
  --color-label-active-bg: #D2CDBE;
  --color-label-bg-alt: #DFDBCF;
  --color-label-text: var(--ink);

  /* Code surfaces inside rendered markdown (`<code>` inline + ``` blocks)
   * and the syntax-highlighter chrome. Match admin.css's `--bg-subtle`
   * so code reads identically across api admin and Forgejo repo views. */
  --color-code-bg: #F4F2EC;
  --color-markup-code-block: #F4F2EC;
  --color-markup-code-inline: #EDEAE2;

  /* Input + button surfaces. Forgejo default zinc-300 borders read cool
   * against our warm birch bg; nudge toward our neutral palette. */
  --color-input-background: #FFFFFF;
  --color-input-border: var(--neutral-300);
  --color-input-border-hover: var(--neutral-600);
  --color-button: var(--neutral-200);

  /* Nav surface (top navbar in Forgejo). Bind to our box-body so the
   * navbar reads as part of the page chrome rather than a separate
   * elevated bar. */
  --color-nav-bg: #FFFFFF;
  --color-nav-hover-bg: #F4F2EC;
  --color-menu: #FFFFFF;

  /* Border radius — fremforge tokens use 8px on cards, 6px on buttons.
   * Forgejo defaults to 4/6px. Expose these as custom props so we can
   * override the selector-level rules below in one place. */
  --ff-radius-button: 6px;
  --ff-radius-card: 8px;
  --ff-radius-input: 6px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-text: #EFEEE9;
    --color-text-dark: #EFEEE9;
    /* Dark-mode muted-text ramp. In light mode, "more muted" = darker
     * (better contrast vs. dark text on light bg). In dark mode the
     * direction flips: "more muted" = lighter (less bright, but must
     * still clear WCAG AA 4.5:1 on the anvil bg).
     * Earlier values bound -light-2/-3 to neutral-700/-600 (#40474D /
     * #5C6770) — those are dark-on-dark, contrast ~1.7-3.0:1. The
     * blockquote body in rendered Markdown READMEs was unreadable
     * (spotted 2026-05-15 on the pnpm/action-setup-pnpm README).
     * New values: progressively dimmer light tones, all >=4.6:1 on
     * #0F1419 anvil bg. */
    --color-text-light: #AEB3B5;     /* 8.3:1 */
    --color-text-light-1: #9BA0A2;   /* 7.0:1 */
    --color-text-light-2: #8B9095;   /* 5.8:1 */
    --color-text-light-3: #7A8085;   /* 4.7:1 — floor for body */

    --color-body: var(--anvil);
    --color-bg: var(--anvil);
    --color-box-body: var(--anvil-soft);
    --color-box-body-highlight: #1F262D;
    --color-box-header: var(--anvil-soft);
    --color-card: var(--anvil-soft);
    --color-light: #252B30;
    --color-light-mimic-enabled: #252B30;

    --color-border: #252B30;
    --color-border-light: #1F262D;
    --color-border-secondary: var(--neutral-700);

    /* Dark-mode neutral secondary set — keep dividers visible against
     * the dark background without becoming a brand colour. */
    --color-secondary: #2F363D;
    --color-secondary-dark-1: #3A434B;
    --color-secondary-dark-2: var(--neutral-700);
    --color-secondary-light-1: #252B30;
    --color-secondary-light-2: #1F262D;
    --color-secondary-light-3: #181E22;

    --color-primary-light-5: #2A4F1B;
    --color-primary-light-6: #1F3914;
    --color-primary-light-7: #142309;

    /* Dark-mode link color. Forge-green (#468A2D) on anvil = 3.5:1 —
     * passes WCAG AA only for large text. Bump to primary-light-3
     * (#80D650) for prose links: 7.5:1 on anvil-soft, clearly brand
     * but readable inline. */
    --color-link: #80D650;
    --color-link-dark-1: #6CBC44;
    --color-link-dark-2: #59A338;

    --color-success-bg: #1F3914;
    --color-success-border: #2A4F1B;
    --color-warning-bg: #3A1E0A;
    --color-warning-border: #5C2F0F;
    --color-error-bg: #3F1212;
    --color-error-border: #5C1A1A;
    --color-info-bg: #14213F;
    --color-info-border: #1A2F5C;

    /* Foreground text on the flash/notice surfaces — must be inverted
     * from the light-mode tokens. Without these the inherited values
     * (forge-green-deep, ember-deep, deep red, deep blue) render dark-
     * on-dark and the flash is unreadable. Spotted live 2026-05-09 on
     * the password-reset success notice ("Din adgangskode er blevet
     * opdateret"). Light tints chosen to clear WCAG AA on each bg:
     *   #C8E6B7 on #1F3914 = 8.2:1
     *   #F4C28A on #3A1E0A = 7.6:1
     *   #FCA5A5 on #3F1212 = 7.4:1
     *   #93C5FD on #14213F = 7.9:1 */
    --color-success-text: #C8E6B7;
    --color-warning-text: #F4C28A;
    --color-error-text: #FCA5A5;
    --color-info-text: #93C5FD;

    /* Dark-mode diff lines — deep tints over the anvil bg, no
     * saturated greens/reds (those read as a different theme). */
    --color-diff-added-row-bg: #182A14;
    --color-diff-added-row-border: #2A4F1B;
    --color-diff-added-word-bg: #2A4F1B;
    --color-diff-removed-row-bg: #2C1414;
    --color-diff-removed-row-border: #5C1A1A;
    --color-diff-removed-word-bg: #5C1A1A;

    --color-label-bg: #252B30;
    --color-label-hover-bg: #2F363D;
    --color-label-active-bg: #3A434B;
    --color-label-bg-alt: #2F363D;
    --color-label-text: #EFEEE9;

    --color-code-bg: #1F262D;
    --color-markup-code-block: #1F262D;
    --color-markup-code-inline: #252B30;

    --color-input-background: var(--anvil-soft);
    --color-input-border: var(--neutral-700);
    --color-input-border-hover: var(--neutral-600);
    --color-button: #252B30;

    --color-nav-bg: var(--anvil-soft);
    --color-nav-hover-bg: #252B30;
    --color-menu: var(--anvil-soft);
  }
}

/* Logo box — give the SVG room without changing layout. */
.ui.menu .item.brand img,
.ui.dropdown .menu .item img.image,
img.ui.avatar.image[alt='logo'] {
  height: 28px;
  width: auto;
}

/* Body uses Inter via the var. System mono cascade for any <code>/<pre>. */
body,
button,
input,
optgroup,
select,
textarea {
  font-family: var(--fonts-regular);
}

code,
kbd,
pre,
samp,
.monospace,
.markdown code,
.markdown pre {
  font-family: var(--fonts-monospace);
}

/* ============================================================
 * Border radius normalization
 *
 * Forgejo defaults to 4px buttons + 6px cards; fremforge tokens
 * are 6/8. Selector-level overrides because radius isn't bound
 * to a CSS variable in Forgejo upstream.
 * ============================================================ */
.ui.button,
.ui.buttons .button,
.ui.input input,
.ui.dropdown,
.ui.selection.dropdown,
input[type='text'],
input[type='search'],
input[type='email'],
input[type='url'],
input[type='password'],
textarea {
  border-radius: var(--ff-radius-input);
}

.ui.segment,
.ui.attached.segment,
.ui.card,
.ui.cards > .card,
.repository-summary,
.ui.menu .item.brand {
  border-radius: var(--ff-radius-card);
}

.ui.attached.header + .ui.attached.segment {
  border-radius: 0 0 var(--ff-radius-card) var(--ff-radius-card);
}

.ui.attached.header {
  border-radius: var(--ff-radius-card) var(--ff-radius-card) 0 0;
}

/* ============================================================
 * Button hover — kill Fomantic's baked-in shadow that doesn't
 * track the theme. Use a flat color shift consistent with the
 * fremforge admin button hover.
 * ============================================================ */
.ui.button:hover,
.ui.button:focus {
  box-shadow: none;
  background-image: none;
}

.ui.primary.button:hover,
.ui.primary.button:focus {
  background-color: var(--color-primary-dark-1);
  box-shadow: none;
}

/* ============================================================
 * Fomantic teal button → fremforge brand green. Forgejo uses
 * `.ui.teal.button` semantically in a few page-level chrome
 * spots (team-view Settings link at templates/org/team/sidebar.tmpl:78
 * is the canonical example; "leave team" / "request access" rows
 * use the same shape). Without this override the button renders
 * Fomantic's default flat teal (#00b5ad) — visually disconnected
 * from the rest of the fremforge admin which is all forge-green.
 *
 * `!important` required because Forgejo's stock CSS bundle order is:
 *   1. fremforge-fonts.css         (our fonts)
 *   2. fremforge-theme.css         (THIS file)
 *   3. index.css                   (Forgejo stock)
 *   4. theme-forgejo-auto.css      (Forgejo stock theme)
 * Our file loads BEFORE Forgejo's bundles, so equal-specificity
 * rules in index.css / theme-forgejo-auto.css win the cascade
 * absent `!important`. Verified live 2026-05-26 (HTML head probe
 * via /user/login → 4 css links in that order).
 *
 * Theme has no semantic role for teal-specifically, so re-aliasing
 * to brand green is on-theme. Caught 2026-05-26 on the team-view
 * page where the Settings button stood out as off-brand.
 * ============================================================ */
.ui.teal.button {
  background-color: var(--forge-green) !important;
  color: #fff !important;
  border: none !important;
}
.ui.teal.button:hover,
.ui.teal.button:focus {
  background-color: var(--forge-green-deep) !important;
  color: #fff !important;
  box-shadow: none !important;
}

/* ============================================================
 * Avatar background palette — Forgejo's auto-generated avatars
 * use a random pastel; clashes with brand. Restrict to neutral
 * with a faint warm cast so unset-avatar users blend in.
 * ============================================================ */
.ui.avatar.image:not([src]),
img.avatar:not([src]) {
  background-color: var(--neutral-200);
}

/* ============================================================
 * Chroma syntax highlighting — Forgejo's upstream chroma class
 * colors are hardcoded hex (no CSS variables). Rebind to a
 * Tomorrow-aligned palette so rendered markdown + diff code
 * matches the admin UI's Prism (same Tomorrow theme).
 *
 * Coverage: keyword/string/comment/name/number/operator/builtin
 * — the meaningful subset. Anything not listed falls back to
 * --color-text via the parent rule.
 * ============================================================ */
.chroma {
  color: var(--color-text);
  background-color: var(--color-code-bg);
}

.chroma .c,  .chroma .c1, .chroma .cm, .chroma .cp, .chroma .cs,
.chroma .ch, .chroma .cpf {
  color: #8E908C;
  font-style: italic;
}

.chroma .k,  .chroma .kc, .chroma .kd, .chroma .kn, .chroma .kp,
.chroma .kr, .chroma .kt {
  color: #8959A8;
}

.chroma .s,  .chroma .s1, .chroma .s2, .chroma .sa, .chroma .sb,
.chroma .sc, .chroma .sd, .chroma .se, .chroma .sh, .chroma .si,
.chroma .sr, .chroma .ss, .chroma .sx, .chroma .dl {
  color: #718C00;
}

/* Functions in blue. */
.chroma .nf, .chroma .nb, .chroma .py {
  color: #4271AE;
}

/* Tags, YAML keys, HTML element names, classes, decorators in brand
 * green — gives structural keys a strong visual anchor that ties
 * code views to fremforge's identity instead of looking like every
 * other Tomorrow-night-themed editor. */
.chroma .nt, .chroma .nc, .chroma .nd, .chroma .ne, .chroma .na {
  color: var(--forge-green-deep);
  font-weight: 500;
}

/* Generic names + variables — fall back to default text color so they
 * don't compete with structural tags/keys for attention. */
.chroma .n, .chroma .ni, .chroma .nl, .chroma .nn, .chroma .nv,
.chroma .nx, .chroma .no, .chroma .vi {
  color: var(--color-text);
}

.chroma .o, .chroma .ow, .chroma .p {
  color: var(--color-text-light);
}

/* Numbers in warm orange — narrowly scoped to .m* classes. Don't widen
 * to .l/.ld/.kc: Chroma's YAML lexer tags bare scalars (including keys
 * in older versions) under `.l` which would repaint half the file. */
.chroma .m, .chroma .mi, .chroma .mf, .chroma .mh, .chroma .mo,
.chroma .mb, .chroma .il {
  color: #B85A0F;
}

/* Booleans, null, constants — purple (keyword family) so they share
 * visual weight with other keywords. */
.chroma .kc {
  color: #8959A8;
}

/* Bare literals (Chroma's YAML lexer puts unquoted values here) and
 * label definitions fall through to default text — they're values, not
 * structure, and shouldn't compete with the brand-green keys above. */
.chroma .l, .chroma .ld {
  color: var(--color-text);
}

.chroma .gi { color: var(--color-success-text); background-color: var(--color-success-bg); }
.chroma .gd { color: var(--color-error-text);   background-color: var(--color-error-bg); }
.chroma .gh, .chroma .gu { color: #4271AE; font-weight: 600; }
.chroma .ge { font-style: italic; }
.chroma .gs { font-weight: 600; }
.chroma .gr, .chroma .gt { color: var(--color-error-text); }

@media (prefers-color-scheme: dark) {
  /* Tomorrow Night-aligned palette for dark mode — slightly higher
   * contrast on the anvil background. */
  .chroma .c, .chroma .c1, .chroma .cm, .chroma .cp, .chroma .cs,
  .chroma .ch, .chroma .cpf { color: #969896; }
  .chroma .k, .chroma .kc, .chroma .kd, .chroma .kn, .chroma .kp,
  .chroma .kr, .chroma .kt { color: #B294BB; }
  .chroma .s, .chroma .s1, .chroma .s2, .chroma .sa, .chroma .sb,
  .chroma .sc, .chroma .sd, .chroma .se, .chroma .sh, .chroma .si,
  .chroma .sr, .chroma .ss, .chroma .sx, .chroma .dl { color: #B5BD68; }
  .chroma .nf, .chroma .nb, .chroma .py { color: #81A2BE; }
  /* Dark-mode brand green for keys/tags — bright enough on anvil-soft
   * (#1F262D contrast >7:1) while staying clearly fremforge. */
  .chroma .nt, .chroma .nc, .chroma .nd, .chroma .ne, .chroma .na { color: #80D650; font-weight: 500; }
  .chroma .n, .chroma .ni, .chroma .nl, .chroma .nn, .chroma .nv,
  .chroma .nx, .chroma .no, .chroma .vi { color: var(--color-text); }
  .chroma .o, .chroma .ow, .chroma .p { color: var(--color-text-light); }
  .chroma .m, .chroma .mi, .chroma .mf, .chroma .mh, .chroma .mo,
  .chroma .mb, .chroma .il { color: #DE935F; }
  .chroma .kc { color: #B294BB; }
  .chroma .l, .chroma .ld { color: var(--color-text); }
  .chroma .gh, .chroma .gu { color: #81A2BE; font-weight: 600; }
  .chroma .gr, .chroma .gt { color: #CC6666; }
}

/* ============================================================
 * File-view header spacing
 *
 * Forgejo stacks three rows above the rendered code block on
 * any file/blob page:
 *   1. .file-header     — line count + file size + language + main actions
 *                         (Rå / Permalink / Skyld / Historie / download / copy)
 *   2. .repo-button-row — secondary actions row (RSS / pencil / trash)
 *   3. file content card
 * Upstream has these butted directly together with no breathing
 * room. Add vertical rhythm between them and a bit more inner
 * padding so the chips don't crowd the header text.
 * ============================================================ */
.file-header,
.file-header-min-h,
.repo-file-view-header,
.ui.segment.file-header {
  padding: 10px 14px !important;
  row-gap: 10px;
  column-gap: 12px;
  margin-bottom: 8px;
}

.file-actions,
.file-header .file-actions {
  gap: 6px;
}

.file-actions .ui.basic.buttons .button,
.file-actions .ui.button {
  margin-left: 4px;
}

.repo-button-row {
  margin: 10px 0;
  gap: 6px;
}

.repo-button-row .button,
.repo-button-row > a {
  margin-right: 6px;
}

/* Tighten code-block line-height a touch for legibility without
 * losing the structural breaks between lines. */
.file-view .chroma,
.repo-file-view .chroma,
.file-view pre,
.repo-file-view pre {
  line-height: 1.55;
}

/* P0-CORP-IDENTITY-VISIBLE (2026-05-23): hide the "Hide email address"
 * toggle on /user/settings/profile. fremforge is a business product —
 * customer commits should carry the corporate identity, not a
 * @noreply.frem.sh placeholder. Forgejo has no native lockdown for
 * this preference, so we hide the UI control + reset existing users
 * via a one-time SQL UPDATE (companion to this commit). The forgejo-
 * keep-email-private-reconciler (hourly) catches any new account or
 * API-flip that bypasses the UI hide.
 *
 * Same UI-hide pattern as the "+ New Organization" link removal in
 * custom/templates/custom/header.tmpl. */
label:has(> input[name="keep_email_private"]) {
  display: none !important;
}

/* P0-CORP-IDENTITY-VISIBLE (2026-05-23, extended): also hide the
 * "Hide activity" toggle on /user/settings/profile. Same shape as
 * keep_email_private — business product policy: customer activity
 * (commits, issues, PRs) should be visible to teammates + auditors.
 * Same enforcement chain: UI lock (this rule), reconciler reset
 * (jobs/forgejo-reconcile), API path blocked by the broad PATCH
 * /api/v1/user/settings intercept. */
label:has(> input[name="keep_activity_private"]) {
  display: none !important;
}

/* P0-EMAIL-CHANGE-LOCKED reverted 2026-05-23 (same day). The blanket
 * email-form hide was too aggressive — Forgejo's built-in mailer
 * verification + the IdP claim winning at login for OIDC users
 * already covers the realistic attack surface ("claim someone else's
 * commits"). Per-tenant email-domain allowlist is the correct deeper
 * enforcement and lives in next-up.md as a separate work item.
 * (No CSS rule emitted here.) */

/* P1-FORGEJO-SKIP-LINK (2026-05-25, audit P1 [ui] frem.sh/user/login).
 * WCAG 2.4.1 Bypass Blocks. Pairs with
 * custom/templates/custom/body_outer_pre.tmpl which injects
 * `<a class="skip-link" href="#main">…</a>` as the first child of
 * <body>. Visually-hidden until keyboard-focused; once focused, slides
 * into the upper-left of the viewport with high contrast against any
 * Forgejo theme.
 *
 * Z-index 9999 to clip above Forgejo's sticky navbar (which uses
 * z-index around 800). */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 8px;
  background: #ffffff;
  color: #0a0a0a;
  padding: 8px 16px;
  border: 2px solid #0a0a0a;
  border-radius: 4px;
  font-weight: 600;
  text-decoration: none;
  z-index: 9999;
}
.skip-link:focus {
  left: 8px;
  outline: 2px solid #0a0a0a;
  outline-offset: 2px;
}


/* P0-HIDE-USER-ARTIFACTS — kebab dropdown styling (M18 2026-05-27).
   Replaces Forgejo's <details class="dropdown"> kebab pattern (iOS
   click-on-summary bug) with plain <button> + <div hidden>. Used by
   shared/user/actions_menu.tmpl AND org/header.tmpl — global CSS so
   it loads on every page that renders the kebab. */
.ff-kebab-menu {
  position: relative;
  display: inline-block;
}
.ff-kebab-summary {
  cursor: pointer;
  user-select: none;
}
.ff-kebab-content {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  /* Tight content-width sizing: shrinks to fit "RSS feed" / "Atom feed"
     / "SSH keys" etc. so the dropdown stays well inside the viewport
     when anchored to the far-right kebab on mobile portrait. The
     previous 200px min-width was the source of the off-screen-left
     clipping on narrow viewports. */
  width: max-content;
  max-width: calc(100vw - 16px);
  background: var(--color-menu, var(--color-secondary-bg, #1a1d22));
  border: 1px solid var(--color-secondary, #2d3138);
  border-radius: var(--border-radius, 6px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
  z-index: 1000;
}
.ff-kebab-content ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.ff-kebab-content ul li > :is(a, button) {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.5rem 0.875rem;
  color: var(--color-text, #e6e6e6);
  background: none;
  border: none;
  text-decoration: none;
  min-height: 2.25rem;
  font-size: 0.95rem;
}
.ff-kebab-content ul li > :is(a, button):hover {
  background: var(--color-hover, rgba(255, 255, 255, 0.06));
}
.ff-kebab-content ul li:first-child > :is(a, button) {
  border-radius: var(--border-radius, 6px) var(--border-radius, 6px) 0 0;
}
.ff-kebab-content ul li:last-child > :is(a, button) {
  border-radius: 0 0 var(--border-radius, 6px) var(--border-radius, 6px);
}
/* Forgejo's {{svg "octicon-..."}} helper emits <svg viewBox="0 0 16 16">
   with no explicit width/height — so it collapses to 0x0 in flex
   containers without sizing. Upstream's details.dropdown CSS handles
   this implicitly; we need to set it ourselves for the .ff-kebab tree. */
/* M18d-r7 (2026-05-27). Reverted debug-red back to currentColor after
   Playwright confirmed CSS+SVG renders fine in the .ff-kebab-content
   structure — the user's "icons missing" was Bunny serving cached HTML
   from before the inline-SVG override landed. */
.ff-kebab-content svg {
  flex-shrink: 0;
  width: 16px !important;
  height: 16px !important;
  min-width: 16px;
  min-height: 16px;
  display: inline-block;
  vertical-align: text-bottom;
}
.ff-kebab-content svg,
.ff-kebab-content svg * {
  fill: currentColor !important;
}


/* ============================================================
 * Stock Forgejo 15.0.2 fix — Actions "Run workflow" branch picker
 *
 * The branch-tag-selector popup (.js-branch-tag-selector) is nested
 * inside #workflow_dispatch_dropdown's dropdown menu. That outer menu
 * is an overflow scroll container, so it CLIPS the absolutely-positioned
 * inner branch popup; meanwhile the flex `.ui.icon.search.input` is wider
 * than the squeezed box. Result: a cut-off "Filter branch or tag…" box
 * with BOTH scrollbars. Confirmed NOT a fremforge regression — our theme
 * doesn't touch the selector; this is an upstream nesting quirk. Scoped
 * to the dispatch dropdown id so no other dropdown is affected.
 * ============================================================ */
#workflow_dispatch_dropdown > .menu {
  /* Don't clip the nested branch popup — let it render at natural size. */
  overflow: visible;
}
#workflow_dispatch_dropdown .js-branch-tag-selector .menu {
  /* Concrete width instead of squeezed-to-parent; kill the h-scrollbar. */
  width: 18rem;
  max-width: calc(100vw - 2rem);
  overflow-x: hidden;
}
#workflow_dispatch_dropdown .js-branch-tag-selector .ui.icon.search.input,
#workflow_dispatch_dropdown .js-branch-tag-selector .ui.icon.search.input input {
  /* The flex search row must fit the popup — box-sizing + min-width:0 so
     the input can shrink instead of forcing horizontal overflow. */
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
#workflow_dispatch_dropdown .js-branch-tag-selector .scrolling.menu {
  /* Vertical scroll for the branch list only; never horizontal. */
  max-height: 14rem;
  overflow-x: hidden;
  overflow-y: auto;
}
