html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}

/* Dashboard card hover effect */
.hover-lift {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.hover-lift:hover {
  transform: translateY(-5px);
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
}

/* Fixed Footer - Always at bottom using flexbox (like AdminLTE) */
.footer-sticky {
  margin-top: auto;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15);
  z-index: 1000;
}

/* ===== HERO SECTION STYLES ===== */

/* Hero Section */
.hero-section {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
    position: relative;
}

/* Animated Background Shapes */
.hero-bg-shapes {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: 1;
}

.shape {
    position: absolute;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.1);
    animation: float 20s infinite ease-in-out;
}

.shape-1 {
    width: 300px;
    height: 300px;
    top: 10%;
    left: -5%;
    animation-delay: 0s;
}

.shape-2 {
    width: 200px;
    height: 200px;
    top: 60%;
    right: 10%;
    animation-delay: 5s;
}

.shape-3 {
    width: 150px;
    height: 150px;
    bottom: 10%;
    left: 50%;
    animation-delay: 10s;
}

@keyframes float {
    0%, 100% {
        transform: translateY(0) rotate(0deg);
    }
    50% {
        transform: translateY(-30px) rotate(180deg);
    }
}

/* Text Gradient */
.text-gradient {
    background: linear-gradient(90deg, #ffd89b 0%, #19547b 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.text-white-90 {
    color: rgba(255, 255, 255, 0.9) !important;
}

.min-vh-70 {
    min-height: 70vh;
}

/* Animations */
.animate-slide-up {
    animation: slideUp 0.8s ease-out;
}

@keyframes slideUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.animate-float {
    animation: floatCard 3s ease-in-out infinite;
}

@keyframes floatCard {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-20px);
    }
}

/* Hover Effects */
.hover-scale {
    transition: all 0.3s ease;
}

.hover-scale:hover {
    transform: scale(1.05);
}

/* Hero Illustration */
.hero-illustration {
    position: relative;
    height: 400px;
}

.hero-card {
    position: relative;
    z-index: 10;
}

.backdrop-blur {
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

.icon-box {
    width: 50px;
    height: 50px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
}

/* Floating Icons */
.floating-icon {
    position: absolute;
    width: 60px;
    height: 60px;
    border-radius: 15px;
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(10px);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}

.floating-icon-1 {
    top: 20%;
    right: 10%;
    animation: bounce 2s infinite ease-in-out;
}

.floating-icon-2 {
    top: 50%;
    right: 5%;
    animation: bounce 2s infinite ease-in-out 0.5s;
}

.floating-icon-3 {
    bottom: 20%;
    right: 15%;
    animation: bounce 2s infinite ease-in-out 1s;
}

.floating-icon-4 {
    top: 35%;
    right: 25%;
    animation: bounce 2s infinite ease-in-out 1.5s;
}

@keyframes bounce {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-15px);
    }
}

/* Feature Cards */
.feature-icon {
    width: 70px;
    height: 70px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Responsive */
@media (max-width: 991px) {
    .hero-section {
        padding: 3rem 0 !important;
    }

    .min-vh-70 {
        min-height: auto;
    }

    .display-2 {
        font-size: 2.5rem;
    }
}

/* =============================================================================
   Epic E61 (Task 2903) - Text-expansion resilience
   =============================================================================
   Translated strings routinely run 30-200% longer than their English source (German
   compound nouns, French verb phrases). These rules make layout survive that instead of
   clipping or overlapping, and use logical (not physical) properties throughout so the same
   rule works unchanged in the right-to-left layout below (Task 2908) instead of needing a
   mirrored override. */

html {
    /* A stack that has a real glyph for Latin, Arabic and CJK scripts rather than falling
       through to a tofu box when a translated string needs a script the previous font lacks. */
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
        Arial, "Noto Sans", "Noto Sans Arabic", "Noto Naskh Arabic", "Noto Sans JP",
        "Noto Sans SC", sans-serif;
}

/* Buttons, nav links and badges size to their content instead of a fixed width, so a longer
   translation wraps or grows the container instead of being clipped. */
.btn, .nav-link, .dropdown-item, .badge {
    min-inline-size: fit-content;
    white-space: normal;
}

/* A label/value pair (settings rows, table cells) that must stay on one line still needs a
   way to show the full text — truncate visually but keep it available via title and to
   assistive technology via aria-label on the same element, never truncate without one. */
.text-truncate-a11y {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-inline-size: 100%;
}

/* Long unbroken tokens (identifiers, hashes, URLs) that appear inside translated sentences
   must not force horizontal scroll on the whole page. */
.text-wrap-anywhere {
    overflow-wrap: anywhere;
}

/* =============================================================================
   Epic E61 (Task 2908) - Right-to-left layout
   =============================================================================
   The <html dir="rtl"> attribute set in _Layout.cshtml already mirrors Bootstrap (which ships
   its own .rtl.min.css, swapped in alongside it) and any element using logical CSS properties
   (margin-inline-start, not margin-left). These rules cover the app's own classes and the
   regions that must stay left-to-right even inside a right-to-left page. */

/* Icons whose meaning is directional (forward/back, expand toward reading direction) flip
   with the page; icons whose meaning is not directional (a git branch glyph, a shield) must
   not, so they opt out explicitly rather than by omission. */
[dir="rtl"] .bi-arrow-repeat,
[dir="rtl"] .bi-box-arrow-in-right,
[dir="rtl"] .bi-box-arrow-right,
[dir="rtl"] .bi-arrow-left,
[dir="rtl"] .bi-arrow-right,
[dir="rtl"] .bi-chevron-left,
[dir="rtl"] .bi-chevron-right {
    transform: scaleX(-1);
}

/* Code, diffs, commit hashes, version numbers and file paths are LTR content by definition
   (a hex hash or a semver string reads the same everywhere) and must not be reordered or
   have their punctuation repositioned by the surrounding RTL paragraph — isolate them with
   both the CSS direction and the Unicode bidi algorithm so mixed content (an RTL sentence
   naming an LTR file path) renders correctly per Task 2908's acceptance criterion. */
.ltr-isolate,
code, pre, kbd, samp,
.diff-view, .commit-hash, .file-path, .terminal-output {
    direction: ltr;
    unicode-bidi: isolate;
    text-align: start;
}

/* =============================================================================
   Epic E61 (Task 2910) - Keyboard operability
   ============================================================================= */

/* First focusable element on every page (see _Layout.cshtml); off-screen until it receives
   focus, at which point it must be the first thing a sighted keyboard user sees. Bootstrap's
   .visually-hidden-focusable un-hides it on focus; this positions the revealed link so it
   doesn't render underneath the sticky navbar. */
.skip-link:focus {
    position: fixed;
    inset-inline-start: 0.5rem;
    top: 0.5rem;
    z-index: 2000;
    padding: 0.5rem 1rem;
    background: #0d6efd;
    color: #fff;
    border-radius: 0.25rem;
    text-decoration: none;
}

/* A visible, contrast-compliant focus outline on every interactive element — including ones
   that only set a Bootstrap :focus box-shadow conditionally (see the .btn/.form-control rule
   above this file already had) or none at all (custom board/tree/diff widgets, Task 2910's
   "tree/grid/diff/board keyboard patterns"). :focus-visible so a mouse click doesn't draw the
   same outline a keyboard Tab does. */
:focus-visible {
    outline: 3px solid #0d6efd;
    outline-offset: 2px;
}

/* Elements that manage their own focus ring (already-styled buttons/inputs above) opt out of
   the generic outline to avoid a doubled ring, without losing focus-visibility altogether. */
.btn:focus-visible, .form-control:focus-visible, .form-check-input:focus-visible {
    outline: none;
}

/* Modal focus trap (Task 2910): while a modal is open, everything outside it is inert to
   Tab/Shift+Tab. The JS in site.js toggles this attribute on <body>; the CSS just enforces
   that inert content is also visually de-emphasised so a sighted user isn't misled about
   what is interactive. */
body.sf-modal-open > :not(.modal, .modal-backdrop) {
    pointer-events: none;
}