/* ============================================================ UTILITIES — Buttons, visually-hidden, kleine Helfer ============================================================ */ /* --- Trefferflächen --------------------------------------------------------- WCAG 2.5.5 wertet die Trefferfläche, nicht die gezeichnete Fläche. Controls, die optisch klein bleiben sollen (dezente Buttons, Slider-Punkte), strecken sie deshalb über ein unsichtbares Pseudo-Element auf --tap-min, statt zu wachsen. Voraussetzung: das Element darf kein overflow: hidden tragen und ::after muss frei sein. */ .tap-target, .btn--sm { position: relative; } .tap-target::after, .btn--sm::after { content: ""; position: absolute; top: 50%; left: 50%; translate: -50% -50%; width: 100%; height: 100%; min-width: var(--tap-min); min-height: var(--tap-min); } /* --- Buttons --------------------------------------------------------------- inline-flex statt inline-block, damit min-height die Trefferfläche sichern kann und Icon+Label ohne Zusatz-Markup zentriert nebeneinander liegen. */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2xs); min-height: var(--tap-min); padding: var(--btn-pad-y) var(--btn-pad-x); white-space: nowrap; background: var(--clr-accent); color: var(--clr-text); font-size: var(--btn-font); line-height: var(--btn-line); text-decoration: none; text-align: center; border: 1px solid var(--clr-accent); border-radius: var(--radius-btn); cursor: pointer; transition: background var(--transition), border-color var(--transition), color var(--transition), transform var(--transition); } /* primary (Default) */ .btn:hover { background: var(--clr-accent-dark); border-color: var(--clr-accent-dark); color: var(--clr-text); } .btn:focus-visible { outline: var(--focus-ring); outline-offset: 2px; } .btn:active { transform: translateY(1px); } .btn[disabled], .btn[aria-disabled="true"] { opacity: 0.6; cursor: not-allowed; transform: none; } /* secondary */ .btn--outline { background: transparent; border-color: var(--clr-text); } .btn--outline:hover { background: var(--clr-glass-bg); border-color: var(--clr-text); color: var(--clr-text); } /* tertiary — ohne Fläche und Rahmen, für Aktionen neben einem primären Button. Unterstrichen, damit der Button nicht allein über die Farbe erkennbar ist. */ .btn--ghost { background: transparent; border-color: transparent; text-decoration: underline; } .btn--ghost:hover { background: var(--clr-glass-bg); border-color: transparent; color: var(--clr-text); } /* Icon-Button — quadratisch, nur ein Icon, Label über aria-label. Das Icon selbst skaliert über font-size (siehe --icon-*). */ .btn--icon { gap: 0; min-width: var(--tap-min); padding: 0; border-radius: 999px; } /* Größenmodifier — Padding ist em-basiert, skaliert mit der font-size. --sm bleibt bewusst optisch klein und holt die 44px über die Trefferfläche; dafür muss min-height hier zurückgenommen werden. */ .btn--sm { min-height: 0; font-size: var(--btn-font-sm); } .btn--lg { font-size: var(--btn-font-lg); } .visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; } /* Inline-Icons (Bootstrap Icons via icon()-Helper). Größe = font-size, Farbe = currentColor. */ .icon { display: inline-block; width: 1em; height: 1em; fill: currentColor; vertical-align: -0.125em; flex: none; } .text-center { text-align: center; } .text-muted { color: var(--clr-text-muted); }