/* Components */

/* Sync status cloud icon */
.sync-icon-syncing svg {
    animation: sync-pulse 1.2s ease-in-out infinite;
}
@keyframes sync-pulse {
    0%, 100% { opacity: 0.35; }
    50% { opacity: 1; }
}

/* Feature Cards: below 500px, always exactly 2 fixed columns - same as the
   original pre-responsive layout, so mobile portrait is a guarantee, not a
   computed minmax() threshold that can fall back to 1 column on a narrower
   real device than expected. At 500px+ (mobile landscape, tablet, desktop)
   .main has no max-width (see layout.css), so auto-fill packs as many
   260px cards as actually fit across the screen instead of being capped to
   a narrow column. 120px min (not 150px) because real phone landscape
   widths often land in the 500-650px range, not the 700px+ this was first
   tuned against - 150px only cleared 3-4 columns above ~700px, so
   landscape was silently still showing 2. justify-content centers the
   occupied columns as a block instead of leaving them stuck to the left
   with empty trailing space when the count doesn't divide the row evenly. */
.cards-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    justify-content: center;
    gap: 12px;
    margin-bottom: 20px;
}

@media (min-width: 500px) {
    .cards-grid {
        grid-template-columns: repeat(auto-fill, minmax(120px, 260px));
    }
}

.card {
    background: var(--card);
    border-radius: var(--radius);
    padding: 16px;
    box-shadow: var(--shadow);
    cursor: pointer;
    transition: transform 0.2s, box-shadow 0.2s;
    position: relative;
    overflow: hidden;
    text-align: center;
    color: inherit;
    text-decoration: none;
    touch-action: manipulation;
}

.card:visited,
.card:visited .card-title,
.card:visited .card-desc,
.card:visited .card-icon {
    color: inherit;
}

.card:active {
    transform: scale(0.98);
}

/* #updateBanner (web SW update banner) - fixed-bottom bar.
   No safe-area padding needed (19 August 2026) - the gesture/3-button nav
   bar clearance is handled natively (MainActivity.java applies real
   WindowInsets as WebView padding), so bottom: 0 already sits above it. */
.bottom-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--primary, #2d5a3d);
    color: #fff;
    padding: 10px 16px;
    align-items: center;
    justify-content: space-between;
    z-index: 1000;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.2);
    gap: 10px;
}

.bottom-banner-text {
    font-size: 0.88rem;
    font-family: var(--font-body, Nunito, sans-serif);
}

.bottom-banner-btn {
    background: #f4a261;
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 6px 14px;
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    font-family: var(--font-body, Nunito, sans-serif);
}

.bottom-banner-btn-outline {
    background: transparent;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-radius: 6px;
    padding: 6px 12px;
    font-size: 0.85rem;
    cursor: pointer;
    font-family: var(--font-body, Nunito, sans-serif);
}

.card-icon, .card-title, .card-desc {
    pointer-events: none;
}

.card-icon {
    font-size: 2rem;
    margin-bottom: 8px;
}

.card-title {
    font-family: 'Fredoka', sans-serif;
    font-weight: 600;
    font-size: 0.95rem;
    margin-bottom: 4px;
}

.card-desc {
    font-size: 0.85rem;
    color: var(--text);
}

.card-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    font-size: 0.85rem;
    padding: 2px 6px;
    border-radius: 8px;
    font-weight: 600;
    pointer-events: none;
}

.card-badge.free {
    background: var(--success);
    color: white;
}

.card-badge.pro {
    background: var(--premium);
    color: white;
}

.card-badge.breeder {
    background: var(--breeder);
    color: white;
}

.card.locked {
    opacity: 0.5;
}

.card.locked::after {
    content: '';
    position: absolute;
    bottom: 8px;
    right: 8px;
    font-size: 1rem;
}

.card-fav {
    position: absolute;
    top: 0;
    left: 0;
    font-size: 1.4rem;
    cursor: pointer;
    z-index: 10;
    line-height: 1;
    padding: 10px;
    touch-action: manipulation;
}

.card-fav.active {
    color: var(--accent);
}

/* Favourites Section */
.favourites-section {
    margin-bottom: 16px;
}

.favourites-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    justify-content: center;
    gap: 12px;
}

@media (min-width: 500px) {
    .favourites-grid {
        grid-template-columns: repeat(auto-fill, minmax(120px, 260px));
    }
}

.fav-card {
    background: var(--card);
    border-radius: var(--radius);
    padding: 20px 16px;
    text-align: center;
    box-shadow: var(--shadow);
    cursor: pointer;
    position: relative;
}
.fav-card.dragging { opacity: 0.4; }
.fav-card.drag-target { outline: 2px solid var(--primary); outline-offset: -2px; }
.fav-drag-handle {
    position: absolute;
    top: 6px;
    right: 8px;
    width: 12px;
    height: 18px;
    cursor: grab;
    touch-action: none;
    user-select: none;
    opacity: 0.4;
    background-image: radial-gradient(circle, var(--text-muted, #666) 1.5px, transparent 1.5px);
    background-size: 6px 6px;
}
.fav-drag-handle:active { cursor: grabbing; opacity: 0.7; }

.fav-card-unstar {
    position: absolute;
    top: 8px;
    left: 8px;
    font-size: 1.2rem;
    color: var(--accent);
    cursor: pointer;
    line-height: 1;
}
.fav-card-unstar:hover, .fav-card-unstar:focus-visible {
    color: var(--danger, #dc3545);
}

.fav-card-icon {
    font-size: 2rem;
    margin-bottom: 8px;
}

.fav-card-title {
    font-family: 'Fredoka', sans-serif;
    font-weight: 600;
    font-size: 0.95rem;
    margin-bottom: 4px;
}

.fav-card-desc {
    font-size: 0.85rem;
    color: var(--text);
}

/* Modal */
.modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0,0,0,0.5);
    z-index: 1000;
    align-items: flex-start;
    justify-content: center;
    overflow-y: auto;
}

.modal.active {
    display: flex;
}

.modal-content {
    background: var(--card);
    border-radius: 0 0 var(--radius) var(--radius);
    width: 100%;
    max-width: 600px;
    min-height: min-content;
    max-height: 100vh;
    overflow-y: auto;
    animation: slideDown 0.2s ease;
}

.modal-content.modal-fullscreen {
    max-width: 100%;
    height: 100vh;
    border-radius: 0;
    display: flex;
    flex-direction: column;
}

/* iOS Safari calculates 100vh against the viewport with its toolbar
   hidden, not what's actually visible - a modal capped at 100vh can
   render taller than the real visible screen, pushing bottom content
   (Save/Send buttons) out of reach until the toolbar happens to be
   collapsed. dvh (dynamic viewport height) tracks the real visible area
   and updates as the toolbar shows/hides; browsers that don't support it
   never enter this block and keep the 100vh fallback above. Placed after
   both base rules so it wins the cascade at equal specificity in
   browsers that do support dvh. */
@supports (max-height: 100dvh) {
    .modal-content {
        max-height: 100dvh;
    }
    .modal-content.modal-fullscreen {
        height: 100dvh;
    }
}

.modal-content.modal-fullscreen .modal-body {
    flex: 1;
    overflow-y: auto;
}

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

.modal-header {
    /* No safe-area padding math here (19 August 2026) - see .header's
       comment in css/layout.css for why. Modals are position: fixed
       overlays within the same WebView, whose own rendering surface is
       already inset natively, so plain flat padding is all this needs.
       Matches .header's exact padding (16px 20px 10px, not a plain 20px)
       so modal headers are the same height as the main app header. */
    padding: 16px 20px 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
    z-index: 10;
}

.modal-title {
    font-family: 'Fredoka', sans-serif;
    font-size: 1.3rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
    color: white;
}

.modal-close {
    /* Fixed 44x44px to match .header-btn (css/layout.css) exactly - .header's
       tallest content is the 44px header-btn circles, so without this,
       .modal-close's font-size+padding-derived height (~40px) left the
       two headers close but not pixel-identical in total height even
       with matching padding. */
    background: none;
    border: none;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    cursor: pointer;
    color: white;
    padding: 0;
}

.modal-body {
    padding: 20px;
}

/* Form Elements */
.form-group {
    margin-bottom: 16px;
}

.form-label {
    display: block;
    font-weight: 600;
    margin-bottom: 8px;
    font-size: 0.95rem;
}

.form-input, .form-select, .form-textarea {
    width: 100%;
    padding: 12px 16px;
    border: 2px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 1rem;
    font-family: inherit;
    transition: border-color 0.2s;
    box-sizing: border-box;
}

.form-textarea {
    resize: vertical;
    min-height: 44px;
}

.form-input:focus, .form-select:focus, .form-textarea:focus {
    outline: none;
    border-color: var(--primary);
}

.form-input[type="date"]::-webkit-calendar-picker-indicator,
.form-input[type="datetime-local"]::-webkit-calendar-picker-indicator {
    filter: var(--date-icon-filter, none);
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px 24px;
    border: none;
    border-radius: var(--radius-sm);
    font-size: 1rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: transform 0.2s, opacity 0.2s;
    width: 100%;
    touch-action: manipulation;
}

.btn * {
    pointer-events: none;
}

.btn:active {
    transform: scale(0.98);
}

.btn-primary {
    background: var(--primary);
    color: white;
}

.btn-secondary {
    background: var(--border);
    color: var(--text);
}

.btn-premium {
    background: linear-gradient(135deg, var(--premium), #8b5cf6);
    color: white;
}

.btn-danger {
    background: var(--danger);
    color: white;
}

/* "More info"-style button: distinct from primary/secondary/danger/premium,
   for expandable/optional content (e.g. the dog form's "More details"
   disclosure) rather than a primary call to action. */
.btn-info {
    background: var(--accent);
    color: white;
}

/* <summary> defaults to display:list-item with a browser-drawn marker;
   restyled here to look and behave like a normal .btn while keeping the
   native <details> disclosure semantics (no extra JS needed). */
summary.btn {
    list-style: none;
}

summary.btn::-webkit-details-marker {
    display: none;
}

summary.btn::after {
    content: '▾';
    margin-left: 4px;
    transition: transform 0.2s;
}

details[open] > summary.btn::after {
    transform: rotate(180deg);
}

/* Results */
.result-box {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
    color: white;
    --text-muted: rgba(255,255,255,0.8);
    padding: 24px;
    border-radius: var(--radius);
    text-align: center;
    margin-top: 20px;
}

.result-value {
    font-family: 'Fredoka', sans-serif;
    font-size: 3rem;
    font-weight: 700;
}

.result-label {
    font-size: 0.95rem;
    opacity: 0.9;
}

/* Premium Modal */
.premium-modal .modal-content {
    background: var(--card);
    color: var(--text);
}

.premium-header {
    text-align: center;
    padding: 30px 20px;
}

.premium-icon {
    font-size: 3rem;
    margin-bottom: 12px;
}

.premium-title {
    font-family: 'Fredoka', sans-serif;
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 8px;
}

.premium-subtitle {
    color: rgba(255,255,255,0.7);
    font-size: 0.95rem;
}

.premium-tiers {
    padding: 0 20px 20px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.tier-card {
    background: rgba(255,255,255,0.1);
    border-radius: var(--radius);
    padding: 20px;
    border: 2px solid transparent;
    cursor: pointer;
    transition: border-color 0.2s;
}

.tier-card.selected {
    border-color: var(--accent);
}

.tier-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

.tier-name {
    font-family: 'Fredoka', sans-serif;
    font-weight: 600;
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    gap: 8px;
}

.tier-price {
    font-family: 'Fredoka', sans-serif;
    font-weight: 700;
    font-size: 1.3rem;
    color: var(--accent);
}

.tier-features {
    font-size: 0.95rem;
    color: rgba(255,255,255,0.8);
}

.tier-features li {
    margin-bottom: 6px;
    list-style: none;
}

.tier-features li::before {
    content: '✓ ';
    color: var(--success);
}

.premium-footer {
    padding: 20px;
    text-align: center;
}

.premium-footer .btn {
    margin-bottom: 12px;
}

.premium-guarantee {
    font-size: 0.85rem;
    color: rgba(255,255,255,0.6);
}

/* Advertisement Banner */
.ad-banner {
    background: var(--card);
    border-radius: var(--radius);
    padding: 16px;
    margin: 20px 0;
    text-align: center;
    box-shadow: var(--shadow);
    position: relative;
}

.ad-banner-text {
    font-size: 0.95rem;
    color: var(--text-muted);
    margin-bottom: 8px;
}

/* Toast */
.toast {
    position: fixed;
    bottom: 100px;
    left: 50%;
    transform: translateX(-50%) translateY(100px);
    background: var(--text);
    color: white;
    padding: 12px 24px;
    border-radius: var(--radius-sm);
    font-size: 0.95rem;
    z-index: 2000;
    opacity: 0;
    transition: transform 0.3s, opacity 0.3s;
}

.toast.show {
    transform: translateX(-50%) translateY(0);
    opacity: 1;
}

/* Settings */
.settings-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 0;
    border-bottom: 1px solid var(--border);
}

.settings-item:last-child {
    border-bottom: none;
}

.settings-label {
    font-weight: 500;
}

.settings-desc {
    font-size: 0.9rem;
    color: var(--text);
}

/* Toggle Switch */
.toggle {
    position: relative;
    width: 50px;
    height: 28px;
}

.toggle input {
    opacity: 0;
    width: 0;
    height: 0;
}

.toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--border);
    border-radius: 28px;
    transition: background 0.3s;
}

.toggle-slider::before {
    content: '';
    position: absolute;
    width: 22px;
    height: 22px;
    left: 3px;
    bottom: 3px;
    background: white;
    border-radius: 50%;
    transition: transform 0.3s;
}

.toggle input:checked + .toggle-slider {
    background: var(--primary);
}

.toggle input:checked + .toggle-slider::before {
    transform: translateX(22px);
}

@keyframes fieldPop {
    0%   { background-color: transparent; }
    20%  { background-color: rgba(244, 162, 97, 0.35); }
    100% { background-color: transparent; }
}

.field-highlight {
    animation: fieldPop 900ms ease-out forwards;
}

/* Notification Centre */
.notif-section-title {
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    padding: 12px 0 6px;
}

.notif-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px 0 12px 9px;
    border-bottom: 1px solid var(--border);
    border-left: 3px solid transparent;
    cursor: default;
    transition: transform 0.15s;
}

/* The icon+content+action line - a plain flex row. Split out from
   .notif-item so a full-width dog name can sit above it as its own line,
   without being squeezed into the icon's width and truncated. */
.notif-row {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* A due reminder that's already had a push sent for it - highlighted rather
   than shown a second time as a separate "notification" row. */
.notif-item.notif-was-sent {
    border-left-color: var(--primary-text);
}

.notif-sent-badge {
    font-size: 0.85rem;
    margin-left: 2px;
    opacity: 0.85;
}

.notif-item.notif-reminder-row .notif-content,
.notif-item.notif-reminder-row .notif-arrow {
    cursor: pointer;
}

.notif-item:last-child {
    border-bottom: none;
}

.notif-item:active {
    transform: scale(0.98);
}

.notif-item.notif-clickable {
    cursor: pointer;
}

/* Not due yet - shown so items already scheduled are visible at a glance,
   but muted so they read as less urgent than the Reminders section above. */
.notif-item.notif-upcoming-row {
    opacity: 0.7;
}

.notif-item.notif-readonly {
    cursor: default;
}

.notif-icon {
    font-size: 1.4rem;
    width: 2rem;
    text-align: center;
    flex-shrink: 0;
}

/* Reminder rows show the dog's own photo instead of a generic type icon -
   round crop matching the .dog-avatar treatment used everywhere else a dog
   photo appears (My Dogs, homepage active dog). */
.notif-icon.notif-icon-photo {
    width: 2rem;
    height: 2rem;
    font-size: 1.1rem;
    border-radius: 50%;
    overflow: hidden;
    background: var(--primary);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
}

.notif-icon.notif-icon-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Only rendered with more than one dog - the photo alone doesn't say which
   dog. Full width so a long name wraps/truncates against the whole row
   rather than being squeezed to the ~2rem photo's width. */
/* Background comes from the inline avatarStyleAttr (sex-based, matches the
   photo below it) so bold white text has guaranteed contrast in both
   light and dark mode - a fixed var(--text-muted) grey doesn't. */
.notif-dog-name {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 700;
    color: #fff;
    padding: 2px 8px;
    border-radius: 8px;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.notif-content {
    flex: 1;
    min-width: 0;
}

.notif-title {
    font-weight: 600;
    font-size: 0.95rem;
}

.notif-desc {
    font-size: 0.9rem;
    color: var(--text-muted);
    margin-top: 2px;
}

.notif-arrow {
    color: var(--text-muted);
    font-size: 1.2rem;
    flex-shrink: 0;
}

.notif-done-btn {
    background: none;
    border-radius: 50%;
    width: 2rem;
    height: 2rem;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, color 0.15s;
    border: 1.5px solid var(--primary-text);
    color: var(--primary-text);
}

.notif-done-btn:active {
    background: var(--primary, #2d5a3d);
    color: #fff;
}

.notif-empty {
    text-align: center;
    padding: 32px 0;
    color: var(--text-muted);
    font-size: 0.95rem;
}


.btn-link {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
    text-decoration: none;
}

.legal-raw-content {
    font-size: 0.95rem;
    line-height: 1.7;
    color: var(--text);
}
.legal-raw-content h2 {
    color: var(--primary-text);
    font-size: 1.1rem;
    margin: 24px 0 10px;
}
.legal-raw-content h3 {
    color: var(--primary-text);
    font-size: 1rem;
    margin: 16px 0 8px;
}
.legal-raw-content p,
.legal-raw-content ul {
    margin-bottom: 12px;
}
.legal-raw-content ul {
    padding-left: 22px;
}
.legal-raw-content li {
    margin-bottom: 6px;
}
.legal-raw-content a {
    color: var(--primary-text);
}
.legal-raw-content .highlight {
    background: var(--highlight-bg, rgba(45,90,61,0.1));
    padding: 16px;
    border-radius: 8px;
    border-left: 4px solid var(--primary, #2d5a3d);
    margin: 16px 0;
}
.legal-raw-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 12px 0;
    font-size: 0.95rem;
}
.legal-raw-content th,
.legal-raw-content td {
    padding: 8px 10px;
    border: 1px solid var(--border);
    text-align: left;
}
.legal-raw-content th {
    background: var(--primary, #2d5a3d);
    color: #fff;
    font-weight: 600;
}
.legal-raw-content tr:nth-child(even) {
    background: var(--bg-alt, rgba(0,0,0,0.04));
}
