/*
 * Polished design inspired by Adobe Lightroom and Apple's minimal aesthetic.
 * The theme supports both light and dark modes via CSS variables. A light
 * weight Open Sans font provides a clean, modern typography. Colours and
 * backgrounds are defined via variables so they can be easily switched.
 */

@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400&display=swap');

/* Default (light) theme variables */
:root {
    --bg-color: #f5f5f5;
    --card-bg: #ffffff;
    --text-color: #333333;
    --primary-color: #0077cc;
    --primary-hover: #005fa3;
    --border-color: #cccccc;
    --muted-text: #666666;
    --upload-border: #999999;
    --upload-highlight: #eef6ff;
    --error-color: #d00000;
    --favorite-color: #f0c420;
    --thumb-shadow: rgba(0, 0, 0, 0.15);
}

/* Dark theme overrides; apply by adding .dark-mode to body */
body.dark-mode {
    --bg-color: #1f1f1f;
    --card-bg: #2a2a2a;
    --text-color: #eeeeee;
    --primary-color: #409aff;
    --primary-hover: #2d71c3;
    --border-color: #444444;
    --muted-text: #bbbbbb;
    --upload-border: #555555;
    --upload-highlight: #2f3a4a;
    --error-color: #ff6b6b;
    --favorite-color: #f0c420;
    --thumb-shadow: rgba(0, 0, 0, 0.35);
}

body {
    font-family: 'Open Sans', sans-serif;
    /* Use a medium weight for better readability across the UI. A weight of 500
       provides more emphasis while remaining balanced with the minimalist
       design. */
    font-weight: 500;
    margin: 20px;
    /* Reserve space at the bottom for the fixed footer. Without this, the
       footer would cover the last portion of the page content. The value
       should be larger than the footer height plus its padding. */
    padding-bottom: 60px;
    background: var(--bg-color);
    color: var(--text-color);
    line-height: 1.5;
}
h1, h2 {
    margin-bottom: 0.6em;
    font-weight: 400;
}
a {
    color: var(--primary-color);
    text-decoration: none;
}
a:hover {
    text-decoration: underline;
}

.error {
    color: var(--error-color);
    margin-bottom: 1em;
}

/* Form styles */
.form-group {
    margin-bottom: 1em;
}
input[type="text"],
input[type="password"],
input[type="date"] {
    width: 100%;
    padding: 0.5em 0.6em;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    background: var(--card-bg);
    color: var(--text-color);
    box-sizing: border-box;
}
button {
    background: var(--primary-color);
    color: #fff;
    border: none;
    padding: 0.6em 1.2em;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.2s ease-in-out;
}
button:hover {
    background: var(--primary-hover);
}

/* Theme toggle button */
/* The toggle is positioned within the site header. The header is positioned
   relatively so this absolute positioning places the toggle to the right
   while vertically centering it. */
.theme-toggle {
    position: absolute;
    right: 15px;
    top: 50%;
    transform: translateY(-50%);
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 50%;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 2px 4px var(--thumb-shadow);
    z-index: 100;
}
.theme-toggle svg {
    fill: var(--text-color);
    width: 22px;
    height: 22px;
}

/* Header bar for company branding */
.site-header {
    background-color: #212129;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    margin: -20px; /* offset the body margin so header spans full width */
    margin-bottom: 20px; /* restore space below header */
}
.site-header .brand {
    /* Use lighter font weight and slightly smaller size for the company name */
    font-size: 21px;
    font-weight: 200;
    color: #b2b2b2;
}
.site-header .brand .brand-highlight {
    /* Highlight the K2 part in bright red and extra bold weight */
    color: #e00e0e;
    font-weight: 900;
}

/* Upload area */
.drop-area {
    border: 2px dashed var(--upload-border);
    border-radius: 8px;
    padding: 2em;
    text-align: center;
    background: var(--card-bg);
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
}
.drop-area.highlight {
    border-color: var(--primary-color);
    background: var(--upload-highlight);
}

/* Progress list */
#progress {
    margin-top: 1em;
    font-size: 0.9em;
    /* default text colour for upload status lines */
    color: var(--text-color);
}

/* Upload status styles. Each row will get either .success or .error */
.upload-status {
    margin-bottom: 0.3em;
}
.upload-status.success {
    color: #2e7d32; /* green tone for success */
}
.upload-status.error {
    color: #c62828; /* red tone for errors */
}

/* Image grids */
.image-grid,
.gallery-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8em;
}

/* Subgallery grid for listing nested galleries in the public view. Mirrors
   the appearance of the image grid but uses the same width rules. */
.subgallery-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8em;
    margin-bottom: 1.2em;
}
.subgallery-grid .gallery-item {
    position: relative;
    width: calc(20% - 0.8em);
    /* Distinguish subgalleries from photos with a slightly darker background.
       A light grey (#ebebeb) improves contrast while still fitting within the
       minimalist aesthetic and acts as a visual divider between gallery
       collections【103115009492333†L130-L139】. */
    background: #ebebeb;
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 1px 3px var(--thumb-shadow);
}
.subgallery-grid .gallery-item img {
    /* Thumbnails in subgalleries should always be contained within a square
       frame. Using an aspect ratio of 1:1 ensures the height matches the
       width. The image is letterboxed when necessary with a white background.
       This prevents portrait images from being forcibly rotated or stretched
       and creates a consistent grid. */
    width: 100%;
    aspect-ratio: 1 / 1;
    height: auto;
    display: block;
    object-fit: contain;
    background-color: #ffffff;
}

/* Style for subgallery labels. Bold titles help differentiate nested
   galleries from individual images and draw the user's attention to
   navigational items. */
.subgallery-grid .gallery-item .filename,
.subgallery-grid .gallery-item .filecount {
    font-weight: 600;
}

/* Gallery header used on public gallery pages when a custom icon is set. It
   aligns the round pictogram with the gallery title. */
.gallery-header {
    display: flex;
    align-items: center;
    gap: 1em;
    margin-bottom: 1em;
}
.gallery-icon {
    width: 70px;
    height: 70px;
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    flex-shrink: 0;
}
.image-grid .img-item,
.gallery-grid .gallery-item {
    position: relative;
    width: calc(20% - 0.8em);
    background: var(--card-bg);
    border-radius: 4px;
    overflow: hidden;
    box-shadow: 0 1px 3px var(--thumb-shadow);
}
.image-grid .img-item img,
.gallery-grid .gallery-item img {
    /* For the main image grid and subgallery grid, make thumbnails square
       and use contain to preserve the original aspect ratio. This avoids
       rotation issues and ensures a unified look across different image
       orientations. */
    width: 100%;
    aspect-ratio: 1 / 1;
    height: auto;
    display: block;
    object-fit: contain;
    background-color: #ffffff;
    border: none;
}

.img-actions {
    position: absolute;
    bottom: 4px;
    left: 4px;
    right: 4px;
    /* Use a semi‑transparent white background so text stands out on dark
       thumbnails. */
    background: rgba(255, 255, 255, 0.75);
    color: var(--text-color);
    font-size: 0.75em;
    padding: 0.2em 0.4em;
    border-radius: 4px;
    display: flex;
    justify-content: space-between;
    opacity: 0;
    transition: opacity 0.2s;
}
.img-item:hover .img-actions {
    opacity: 1;
}

/* Links within the image actions should inherit the text colour for better
   contrast on the white overlay. */
.img-actions a {
    color: var(--text-color);
}

/* Flag badges: clickable coloured dots for marking images */
.flag-badge {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid #fff;
    background: rgba(0, 0, 0, 0.3);
    cursor: pointer;
    transition: background 0.2s ease-in-out;
    box-sizing: border-box;
    z-index: 2;
}
.flag-badge.red {
    background: rgba(220, 53, 69, 0.9);
}
.flag-badge.yellow {
    background: rgba(255, 193, 7, 0.9);
}
.flag-badge.green {
    background: rgba(40, 167, 69, 0.9);
}
.flag-badge.none {
    background: rgba(0, 0, 0, 0.3);
}

/* Favorite star */
.favorite-star {
    position: absolute;
    /* Slightly raise the favorite star so it sits closer to the top edge.
       The negative top value positions the star partly outside its container
       which visually aligns it better with the image's corner. */
    top: -3px;
    left: 6px;
    font-size: 20px;
    color: rgba(255, 255, 255, 0.8);
    cursor: pointer;
    z-index: 3;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
    transition: color 0.2s;
}
.favorite-star.active {
    color: var(--favorite-color);
}

/* Zip download link styled as a button */
.zip-download {
    display: inline-block;
    margin: 0.6em 0;
    padding: 0.5em 1.0em;
    background: var(--primary-color);
    color: #fff;
    border-radius: 4px;
    text-decoration: none;
    font-size: 0.9em;
}
.zip-download:hover {
    background: var(--primary-hover);
}

/* Admin indicator bar displayed when logged in. Appears below the site
   header to clearly distinguish admin views. Contains a label on the left
   and a logout link on the right. */
.admin-bar {
    background-color: #bc0000;
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 12px;
    height: 32px;
    font-size: 0.85em;
    box-shadow: 0 1px 3px var(--thumb-shadow);
    /* align flush with the header by offsetting the body margin; remove extra top margin */
    margin: -20px;
    margin-bottom: 20px;
}
.admin-bar .icon {
    /* Provide spacing around the gear icon and scale it slightly larger */
    margin-right: 6px;
    font-size: 1.1em;
}
.admin-bar .admin-link {
    display: flex;
    align-items: center;
    color: #ffffff;
    text-decoration: none;
    font-weight: 500;
}
.admin-bar .admin-link:hover {
    text-decoration: underline;
}
.admin-bar .logout {
    color: #ffffff;
    text-decoration: underline;
}
.admin-bar .logout:hover {
    text-decoration: none;
}
.admin-bar a {
    color: #ffffff;
    text-decoration: underline;
}
.admin-bar a:hover {
    text-decoration: none;
}

/*
 * Breadcrumb navigation for nested galleries.
 *
 * Shows the hierarchy of galleries separated by slashes. Parent galleries
 * are links with a lighter grey colour, while the current gallery is
 * darker and bold. The breadcrumb container uses inline flex to allow
 * wrapping on smaller screens.
 */
.breadcrumbs {
    margin-bottom: 0.6em;
    font-size: 1.4em;
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3em;
}
.breadcrumbs a {
    color: #787878;
    text-decoration: none;
}
.breadcrumbs a:hover {
    text-decoration: underline;
}
.breadcrumbs .breadcrumb-current {
    color: #333333;
    font-weight: 600;
}
/* Align breadcrumbs next to the icon in the gallery header */
.gallery-header .breadcrumbs-wrapper {
    flex: 1;
}
/* Navigation links for the single image view */
.image-nav a {
    color: var(--primary-color);
    text-decoration: none;
    padding: 0.3em 0.8em;
}
.image-nav a:hover {
    text-decoration: underline;
}

/* Top bar for single image view containing navigation and controls */
.image-top-bar {
    /* Use a white background for the top bar to provide contrast against dark
       images. Text and icons inherit the default text colour from the
       surrounding context (var(--text-color)). */
    background-color: #ffffff;
    color: var(--text-color);
    padding: 0.4em 0.6em;
    margin-top: 0.4em;
    display: flex;
    align-items: center;
    border-radius: 4px;
    box-shadow: 0 1px 3px var(--thumb-shadow);
}
.image-top-bar a {
    color: var(--primary-color);
    text-decoration: none;
    font-size: 0.95em;
}
.image-top-bar a:hover {
    text-decoration: underline;
}
.image-top-bar .flag-badge {
    position: static;
    margin-right: 0.4em;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    /* Use a neutral border colour on light background */
    border: 2px solid var(--border-color);
    box-sizing: border-box;
}
.image-top-bar .favorite-star {
    position: static;
    font-size: 22px;
    /* Use a neutral dark colour for the inactive star on light backgrounds */
    color: rgba(0, 0, 0, 0.5);
    cursor: pointer;
    text-shadow: none;
}
.image-top-bar .favorite-star.active {
    color: var(--favorite-color);
}

/* Single image view: scale portrait images based on height instead of width.
   The image will fit within 80% of the viewport height. By using object-fit:
   contain, we ensure the aspect ratio is preserved and white borders are
   shown for portrait images. */
.image-view img {
    max-height: 80vh;
    max-width: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    background-color: #ffffff;
}

/* Display the filename below each image without extension */
.gallery-item .filename {
    margin-top: 4px;
    font-size: 0.85em;
    text-align: center;
    color: var(--muted-text);
    word-break: break-all;
    padding-bottom: 6px;
}

/* Display the count of photos in a gallery (subgallery overview) */
.gallery-item .filecount {
    margin-top: 2px;
    font-size: 0.75em;
    text-align: center;
    color: var(--muted-text);
    padding-bottom: 6px;
}

/* File count display within gallery cards (admin lists) */
.gallery-info .filecount {
    margin-top: 0.2em;
    font-size: 0.75em;
    color: var(--muted-text);
}

/* Preview thumbnails in index list */
.gallery-preview {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: 4px;
    margin-right: 8px;
    box-shadow: 0 1px 3px var(--thumb-shadow);
}

/* Panel: used to visually separate the new gallery creation form. Adds a
   subtle border, shadow and padding. */
.panel {
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 1.2em;
    margin-bottom: 1.6em;
    box-shadow: 0 1px 3px var(--thumb-shadow);
}
.panel h2 {
    margin-top: 0;
    margin-bottom: 0.8em;
    font-weight: 400;
}

/* Gallery list on the admin dashboard. Uses a flexbox grid to display
   gallery cards evenly spaced. */
.gallery-list-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 1em;
}
.gallery-card {
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    box-shadow: 0 1px 3px var(--thumb-shadow);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    width: calc(25% - 1em);
    min-width: 200px;
}
.gallery-card img {
    /* Display all thumbnails in a square frame. Using aspect-ratio ensures
       that height matches width. `object-fit: contain` preserves the
       original aspect ratio of the photo and letterboxes the remaining
       space. The white background makes the letterbox visible. */
    width: 100%;
    aspect-ratio: 1 / 1;
    height: auto;
    display: block;
    object-fit: contain;
    background-color: #ffffff;
}
.gallery-card .gallery-info {
    padding: 0.7em 0.8em;
    flex: 1;
}
.gallery-card .gallery-info .title {
    font-weight: 400;
    margin-bottom: 0.2em;
}
.gallery-card .gallery-info .slug {
    font-size: 0.8em;
    color: var(--muted-text);
    margin-bottom: 0.2em;
    word-break: break-all;
}
.gallery-card .gallery-info .expire {
    font-size: 0.75em;
    color: var(--muted-text);
}
.gallery-card .gallery-actions {
    display: flex;
    justify-content: space-around;
    padding: 0.6em 0.8em;
    border-top: 1px solid var(--border-color);
    font-size: 0.85em;
}
.gallery-card .gallery-actions a {
    color: var(--primary-color);
    text-decoration: none;
}
.gallery-card .gallery-actions a:hover {
    text-decoration: underline;
}

/* Responsive adjustments for gallery cards on smaller screens */
@media (max-width: 1024px) {
    .gallery-card {
        width: calc(33.333% - 1em);
    }
}
@media (max-width: 768px) {
    .gallery-card {
        width: calc(50% - 1em);
    }
}
@media (max-width: 480px) {
    .gallery-card {
        width: 100%;
    }
}

/* Responsive breakpoints */
@media (max-width: 1024px) {
    .image-grid .img-item,
    .gallery-grid .gallery-item {
        width: calc(25% - 0.8em);
    }
    .subgallery-grid .gallery-item {
        width: calc(25% - 0.8em);
    }
}
@media (max-width: 768px) {
    .image-grid .img-item,
    .gallery-grid .gallery-item {
        width: calc(33.333% - 0.8em);
    }
    .subgallery-grid .gallery-item {
        width: calc(33.333% - 0.8em);
    }
}
@media (max-width: 480px) {
    .image-grid .img-item,
    .gallery-grid .gallery-item {
        width: calc(50% - 0.8em);
    }
    .subgallery-grid .gallery-item {
        width: calc(50% - 0.8em);
    }
}

/*
 * Site footer
 *
 * A subtle footer that appears on every page. It uses the same dark grey
 * background as the header for consistency and white text for sufficient
 * contrast. According to accessibility guidelines, high‑contrast text
 * improves readability; however, pure white on pure black can be too
 * extreme【33303871343148†L59-L66】. A dark grey (#212129) paired with white
 * text meets the minimum contrast ratio recommended by WCAG 2.0 (4.5:1 for
 * normal text)【127827519818716†L94-L118】 while remaining comfortable to read.
 */
/*
 * Footer update (June 2026)
 *
 * Place the footer flush against the bottom of the viewport so it is always
 * visible, even when the page content is short. The footer has a white
 * background that fades to a light grey at the top to create a subtle
 * shadow effect. Text uses a medium grey colour for better readability
 * and reduced contrast. Use `position: fixed` to anchor the footer and
 * offset the body's bottom padding to prevent content from being hidden.
 */
.site-footer {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(to top, #ffffff 0%, #d7d7d7 100%);
    color: #8c8c8c;
    font-size: 10pt;
    padding: 0.4em 1em;
    /* Offset the body margin so the footer spans the full width of the page.
       Matching the header's negative horizontal margins ensures a consistent
       edge alignment. */
    margin: 0 -20px;
    /* Center the footer text for a balanced appearance across the page. */
    text-align: center;
    z-index: 1000;
}
.site-footer a {
    color: #8c8c8c;
    text-decoration: underline;
}
.site-footer a:hover {
    text-decoration: none;
}