/* Component Utility Classes */

/* Patreon tier badge colors */
.badge-tier-hero       { background-color: #c0392b; color: #fff; }
.badge-tier-expert     { background-color: #2471a3; color: #fff; }
.badge-tier-companion  { background-color: #17a589; color: #fff; }
.badge-tier-master     { background-color: #1c2833; color: #fff; }
.badge-tier-immortal   { background-color: #1c2833; color: #d4af37; }

/* Form input width utilities */
.input-width-60 {
    width: var(--input-width-sm);
}

.input-width-120 {
    width: var(--input-width-md);
}

/* Skill input group styling for consistent layout */
.skill-input-group .input-group-text {
    width: var(--input-width-md);
}

.skill-input-group .form-control {
    width: var(--input-width-sm);
}

/* Ability score table styling */
.ability-score-input {
    width: var(--input-width-sm);
}

/* Monster form specific styling */
.monster-form .form-control-sm {
    font-size: var(--font-size-sm);
}

/* Form inputs with theme support */
.form-control, .form-select {
    background-color: var(--content-bg);
    border-color: var(--border-input);
    color: var(--text-primary);
}

.form-control:focus, .form-select:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 0.2rem rgba(var(--primary-color-rgb), 0.25);
}

/* Theme-aware input-group-text styling */
.input-group-text {
    background-color: var(--hover-bg);
    border-color: var(--border-input);
    color: var(--text-primary);
}

/* Modern UI improvements - button states and interactions */
.btn {
    transition: all 0.2s ease-in-out;
    min-height: 44px; /* Minimum touch target size (WCAG 2.1) */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

/* .btn-link is text, not a control: opt it out of the button box model so it
   flows inline in table cells and headings instead of becoming a 44px block. */
.btn-link {
    min-height: 0;
    display: inline;
    text-align: inherit;
    vertical-align: baseline;
}

.btn:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

.btn:disabled,
.btn[aria-busy="true"] {
    opacity: 0.6;
    cursor: not-allowed;
    pointer-events: none;
}

/* Loading spinner for async operations */
.spinner-border-sm {
    width: 1rem;
    height: 1rem;
    border-width: 0.15em;
}

/* Form select improvements */
.form-select:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    background-color: var(--hover-bg);
}

/* Alert improvements */
.alert {
    animation: slideDown 0.3s ease-out;
}

@keyframes slideDown {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Better focus indicators */
.form-control:focus,
.form-select:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 0.2rem rgba(var(--primary-color-rgb), 0.25);
    outline: none;
}

/* Responsive form adjustments */
@media (max-width: 768px) {
    .skill-input-group .input-group-text {
        width: 100px;
        font-size: 0.75rem;
    }
    
    .input-width-120 {
        width: 100px;
    }
}

/* Quick Access Panel Styling */
#quickAccessPanel, #indexQuickAccessPanel {
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

#quickAccessPanel .form-select, #indexQuickAccessPanel .form-select {
    background-color: transparent;
    border: none;
    color: white;
    font-size: 0.875rem;
    padding: 0.25rem 1.5rem 0.25rem 0;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

#quickAccessPanel .form-select:focus, #indexQuickAccessPanel .form-select:focus {
    border: none;
    box-shadow: none;
    outline: 1px solid rgba(255, 255, 255, 0.5);
    outline-offset: 1px;
}

#quickAccessPanel .form-select option, #indexQuickAccessPanel .form-select option {
    background-color: var(--content-bg);
    color: var(--text-primary);
}

/* Index page specific styling */
#indexQuickAccessContainer {
    margin-top: 1rem;
}

#indexQuickAccessPanel {
    box-shadow: var(--shadow-sm);
}

/* Responsive quick access panel */
@media (max-width: 768px) {
    #quickAccessPanel .form-select, #indexQuickAccessPanel .form-select {
        font-size: 0.75rem;
        padding: 0.125rem 1rem 0.125rem 0;
    }
    
    #indexQuickAccessContainer {
        margin-top: 0.5rem;
    }
}

/* Dense admin table styling to replace page-local inline styles. */
.users-table-compact {
    font-size: var(--font-size-sm);
}

.users-table-filters th {
    padding: var(--spacing-xs) 0.4rem;
}

.users-table-filters input,
.users-table-filters select {
    min-width: var(--input-width-sm);
}

/* Footer legal attribution shared style. */
.legal-attribution {
    font-size: 0.75rem;
    line-height: 1.35;
    display: block;
}
/* ---------------------------------------------------------------------------
   Monster Forge entry mechanics (feature 042, US1)

   Each entry in Traits / Actions / Bonus Actions / Reactions / Legendary
   Actions carries ~35 mechanical attributes. Showing them all flat buries the
   two fields an author reaches for most, so they sit in five <details> groups.
   The rule that keeps a long form navigable (FR-007): the name and description
   of every entry stay visible without expanding anything — only the mechanical
   detail collapses.
   --------------------------------------------------------------------------- */

.entry-mechanics {
    border-left: 2px solid var(--border-color);
    padding-left: var(--spacing-sm);
    margin-top: var(--spacing-xs);
}

.entry-group {
    border-top: 1px solid var(--border-color);
}

.entry-group-summary {
    cursor: pointer;
    padding: var(--spacing-xs) 0;
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--text-muted);
    list-style-position: inside;
}

.entry-group-summary:hover {
    color: var(--text-primary);
}

/* Focus must be visible on the summary — it is the only control that opens
   the group for a keyboard user. */
.entry-group-summary:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
    border-radius: 2px;
}

.entry-group-body {
    padding-bottom: var(--spacing-sm);
}

/* FR-001b: a collapsed group holding any stored value says so, otherwise
   progressive disclosure hides data the author has no reason to look for.
   Redundant once the group is open, so it disappears there. */
.entry-group-dot {
    color: var(--primary-color);
    font-size: 0.6rem;
    vertical-align: middle;
    margin-left: var(--spacing-xs);
}

.entry-group[open] > .entry-group-summary .entry-group-dot {
    display: none;
}

/* FR-019: the generated sentence sits directly beneath the entry's own text and
   must never be mistaken for it. The dashed border, muted italic type and
   hover-only background all say "not stored" — the editable textarea above it
   is solid-bordered, upright and full-contrast. */
.entry-preview {
    margin-top: var(--spacing-xs);
    padding: var(--spacing-xs) var(--spacing-sm);
    border: 1px dashed var(--border-light);
    border-radius: var(--border-radius-sm);
    background: var(--hover-bg);
}

.entry-preview-label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-xs);
    flex-wrap: wrap;
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.entry-preview-text {
    font-size: var(--font-size-sm);
    font-style: italic;
    color: var(--text-secondary);
}

.entry-preview-actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
}

/* Small enough not to compete with Save, but a real button — adopting is a
   deliberate act, not something a stray click should do (FR-020). */
.entry-preview-adopt,
.entry-preview-undo {
    padding: 0 var(--spacing-xs);
    font-size: var(--font-size-sm);
    text-transform: none;
    letter-spacing: normal;
}

/* Rules glossary marks (#687, spec 059): a link to the term that reads as body text, with a dotted
   underline to show it has a definition. Printed as plain text. */
a.gloss {
    color: inherit;
    text-decoration: underline dotted;
    text-underline-offset: 0.2em;
    cursor: help;
}
a.gloss:hover,
a.gloss:focus-visible {
    color: inherit;
    text-decoration-style: solid;
}
.gloss-popover {
    max-width: min(22rem, calc(100vw - 2rem));
}
@media print {
    a.gloss {
        text-decoration: none;
    }
}

/* Spec 061 (#681): a footnote marker beside a part the printed SRD shows differently. */
sup.errata-mark {
    margin-left: 0.1em;
    font-weight: 600;
}
sup.errata-mark a {
    text-decoration: none;
}
sup.errata-mark a:hover,
sup.errata-mark a:focus-visible {
    text-decoration: underline;
}
