/*
 * gabrielobreja.com
 *
 * Bootstrap 5.3 does the layout; this is only the identity on top of it. The palette is
 * deliberately quiet: the work is ceramics, mostly warm earth tones against neutral
 * backgrounds, and a site that competes with the photographs is a site that hides them.
 *
 * Written against Bootstrap's own custom properties so the whole thing follows the
 * viewer's light or dark preference without a second stylesheet.
 */

:root {
    --gabi-ink: #23201d;
    --gabi-clay: #a5674f;
    --gabi-clay-dark: #8d5540;
    --gabi-paper: #faf8f5;
    --gabi-line: rgba(35, 32, 29, .12);
}

@media (prefers-color-scheme: dark) {
    :root {
        --gabi-ink: #ece8e3;
        --gabi-clay: #c98a6e;
        --gabi-clay-dark: #e0a184;
        --gabi-paper: #17150f;
        --gabi-line: rgba(236, 232, 227, .14);
    }
}

body {
    background: var(--gabi-paper);
    color: var(--gabi-ink);
    font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
    -webkit-font-smoothing: antialiased;
}

.skip-link {
    position: absolute;
    top: .5rem;
    left: .5rem;
    z-index: 1080;
    background: var(--gabi-paper);
    padding: .5rem .75rem;
    border-radius: .25rem;
}

/* ---------------------------------------------------------------- navigation */

.site-nav {
    background: color-mix(in srgb, var(--gabi-paper) 92%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--gabi-line);
}

/* The wordmark. Handwriting from the 2013 site, recoloured: its #5E89C2 was a cool
   periwinkle picked for a white page, and it is the one hue here that would belong to
   nothing else. Size is set on the link so both halves inherit it, which is what the
   original did with a single font-size on a single div. */
.navbar-brand {
    display: flex;
    align-items: baseline;
    gap: .3em;
    line-height: 1.1;
    text-decoration: none;
    font-family: "RabioHead", Georgia, serif;
    font-size: 1.55rem;
}

@media (min-width: 992px) {
    .navbar-brand {
        font-size: 1.7rem;
    }
}

.brand-name {
    color: var(--gabi-ink);
}

/* lowercase here rather than in the lang files: they say "Ceramist" and are reused in the
   page title, while the wordmark has always read "ceramist".

   No letter-spacing, unlike the small caps this replaces. Tracked-out handwriting reads as
   a rendering fault. Clay on paper is about 4.26:1, which fails AA for normal text and is
   why the old .72rem role was a contrast bug; at the inherited 1.7rem it is large text,
   where the threshold is 3:1. Keep these two facts together: shrinking the role below 24px
   reintroduces the failure. */
.brand-role {
    color: var(--gabi-clay);
    text-transform: lowercase;
}

.brand-role::before {
    /* The trailing space is preserved; the leading one comes from the flex gap, because a
       space at the start of a flex item would be collapsed away. */
    content: "- ";
}

.site-nav .nav-link {
    /* Slightly recessed, so the current section can stand out by being fully opaque
       rather than by relying on a hairline nobody notices. */
    color: color-mix(in srgb, var(--gabi-ink) 62%, transparent);
    letter-spacing: .1em;
    text-transform: uppercase;
    font-size: .78rem;
    padding-inline: .85rem;
    position: relative;
}

/*
 * The current section, made actually visible.
 *
 * The first version marked it with a 1px clay underline and left the label the same colour
 * as every other link, which is invisible in practice. Now it is full-strength ink, in the
 * clay colour, over a 2px rule. An ::after rather than a border-bottom so the text does
 * not shift by a pixel when the state changes.
 */
.site-nav .nav-link.active {
    color: var(--gabi-clay);
}

.site-nav .nav-link.active::after {
    content: "";
    position: absolute;
    left: .85rem;
    right: .85rem;
    bottom: .15rem;
    height: 2px;
    border-radius: 2px;
    background: var(--gabi-clay);
}

.site-nav .nav-link:hover,
.site-nav .nav-link:focus-visible {
    color: var(--gabi-ink);
}

.lang-switch .nav-link {
    border: 1px solid var(--gabi-line);
    border-radius: 999px;
    padding-inline: .7rem;
    font-size: .72rem;
}

.navbar-toggler {
    border-color: var(--gabi-line);
}

/* Bootstrap serves the light-on-dark version of this glyph from exactly two selectors,
   `.navbar[data-bs-theme=dark]` and `[data-bs-theme=dark] .navbar-toggler-icon`, and from
   nowhere else; its default is rgba(33, 37, 41, .75), a near-black.

   This site carries no data-bs-theme at all. It goes dark through its own
   prefers-color-scheme rules, which Bootstrap cannot see, so the bar becomes #17150f while
   the glyph stays near-black: the button is still there and still clickable, it just has
   almost no contrast against what is behind it.

   Inverting the shipped glyph fixes it and leaves one definition to maintain instead of a
   second copy of the SVG data URI that has to be kept in step. */
@media (prefers-color-scheme: dark) {
    .navbar-toggler-icon {
        filter: invert(1) opacity(.85);
    }
}

/* ---------------------------------------------------------------------- hero */

.hero {
    background: #000;
}

/*
 * The slider is two layers, and the reason is the source material.
 *
 * These photographs are small and mostly portrait: 317x600, 412x600, 495x600. A single
 * full-bleed image with object-fit:cover scaled the first one 3.6x across a 1790px hero
 * and cropped the vertical middle, so a portrait of the artist rendered as a blurry
 * close-up of his chin. Contain fixes the crop; a blurred copy of the same file fills the
 * space that contain leaves, which is what a gallery wants anyway.
 */
.hero-slide {
    position: relative;
    height: clamp(320px, 62vh, 660px);
    overflow: hidden;
    background: #0b0a09;
}

.hero-backdrop {
    position: absolute;
    /* Inset negatively so the blur has material past the edges and does not fade out. */
    inset: -6%;
    background-size: cover;
    background-position: center;
    /* Heavier blur and darker than looks necessary on paper. At 34px the photograph's own
       frame was still legible in the backdrop, which read as two vertical seams either
       side of the image rather than as ambient fill. */
    filter: blur(56px) brightness(.32) saturate(.7);
    transform: scale(1.08);
}

/* A soft vignette over the backdrop, so the contained photograph sits in the brighter
   middle instead of competing with an evenly lit field. */
.hero-slide::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(ellipse at center, transparent 45%, rgba(0, 0, 0, .55) 100%);
}

.hero-image {
    z-index: 1;
}

.hero-image {
    position: relative;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
}

.hero .carousel-caption {
    background: linear-gradient(transparent, rgba(0, 0, 0, .7));
    left: 0;
    right: 0;
    bottom: 0;
    padding: 3.5rem 0 1.25rem;
    text-align: left;
}

.hero .carousel-caption h2 {
    font-size: clamp(1.1rem, 3vw, 1.9rem);
    letter-spacing: .04em;
    margin: 0;
}

/* ------------------------------------------------------------------ headings */

.section-title {
    font-size: clamp(1.3rem, 2.6vw, 1.9rem);
    letter-spacing: .03em;
    margin-bottom: .25rem;
}

.section-lead {
    color: var(--gabi-clay);
    letter-spacing: .16em;
    text-transform: uppercase;
    font-size: .72rem;
    margin-bottom: 1.75rem;
}

/* -------------------------------------------------------------------- tiles */

.tile {
    display: block;
    position: relative;
    overflow: hidden;
    border-radius: .35rem;
    background: color-mix(in srgb, var(--gabi-ink) 6%, transparent);
    text-decoration: none;
    color: inherit;
}

/*
 * Absolute fill rather than height:100%.
 *
 * The first version combined aspect-ratio on the tile with height:100% on the image and
 * h-100 from Bootstrap on the anchor. Those three fight each other inside a grid row:
 * some covers letterboxed and one appeared to escape its rounded box. Pinning the image
 * to the tile's edges removes the ambiguity, and the tile's aspect-ratio alone decides
 * the shape.
 */
.tile img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .45s ease;
}

/* A tile with no aspect-ratio (a wide work) sizes to its image instead. */
.tile:not(.tile-ratio) img {
    position: static;
    height: auto;
}

.tile:hover img,
.tile:focus-visible img {
    transform: scale(1.04);
}

.tile-ratio {
    aspect-ratio: 4 / 3;
}

.tile-label {
    position: absolute;
    inset: auto 0 0 0;
    padding: 2.25rem .9rem .7rem;
    background: linear-gradient(transparent, rgba(0, 0, 0, .72));
    color: #fff;
}

.tile-label .name {
    display: block;
    letter-spacing: .03em;
    font-size: 1rem;
}

.tile-label .count {
    font-size: .72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: .85;
}

/* --------------------------------------------------------------- work grid */

/* The legacy schema has an isDouble flag, so a work marked wide spans two columns
   instead of being cropped into a square. */
.work-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: .75rem;
}

@media (min-width: 768px) {
    .work-grid {
        grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
        gap: 1rem;
    }
}

.work-grid .is-wide {
    grid-column: span 2;
}

.work {
    border: 0;
    padding: 0;
    background: none;
    cursor: zoom-in;
    text-align: left;
    width: 100%;
}

.work figcaption {
    font-size: .8rem;
    padding: .45rem .1rem 0;
    color: var(--gabi-ink);
    opacity: .8;
}

/* ------------------------------------------------------------------ article */

/*
 * The CV and contact bodies.
 *
 * These arrive as plain semantic HTML now: p, ul, li, strong, em, u. The colours and font
 * sizes the 2013 CMS embedded are stripped by the sanitiser, because navy #000080 chosen
 * for a white page is invisible here and that is precisely how this page looked before.
 * So all of the appearance is decided in one place, and it is this block.
 */
/* The document column. Centred on wide screens so a 68ch measure does not sit against the
   left edge with half the window empty beside it. */
.page-doc {
    max-width: 70ch;
    margin-inline: auto;
}

.page-body {
    max-width: 68ch;
    font-size: 1.02rem;
    line-height: 1.8;
    color: color-mix(in srgb, var(--gabi-ink) 92%, transparent);
}

.page-body > :first-child {
    margin-top: 0;
}

.page-body p {
    margin: 0 0 1.05em;
}

/* A paragraph that is only an emphasised run acts as a section heading in this content
   ("Domenii de activitate:", "Linie genealogică ..."), so give it room to breathe rather
   than letting it run into the list beneath it. */
.page-body p > strong:only-child,
.page-body p > u:only-child,
.page-body p > strong > u:only-child {
    display: inline-block;
    margin-top: .8em;
    color: var(--gabi-ink);
    letter-spacing: .01em;
}

.page-body strong {
    color: var(--gabi-ink);
    font-weight: 600;
}

.page-body u {
    text-decoration-color: color-mix(in srgb, var(--gabi-clay) 60%, transparent);
    text-decoration-thickness: 1px;
    text-underline-offset: .22em;
}

.page-body em {
    color: color-mix(in srgb, var(--gabi-ink) 82%, transparent);
}

.page-body ul,
.page-body ol {
    margin: 0 0 1.15em;
    padding-left: 1.35em;
}

.page-body li {
    margin-bottom: .35em;
}

.page-body ul {
    list-style: none;
    padding-left: 1.1em;
}

/* Clay markers, and hanging so the text lines up as a column rather than stepping in. */
.page-body ul > li {
    position: relative;
}

.page-body ul > li::before {
    content: "";
    position: absolute;
    left: -1.1em;
    top: .78em;
    width: .38em;
    height: 1px;
    background: var(--gabi-clay);
}

.page-body h2,
.page-body h3,
.page-body h4 {
    font-size: clamp(1.05rem, 2vw, 1.25rem);
    letter-spacing: .02em;
    margin: 1.8em 0 .6em;
    color: var(--gabi-ink);
}

.page-body a {
    color: var(--gabi-clay-dark);
    text-underline-offset: .2em;
}

.page-body img {
    max-width: 100%;
    height: auto;
    border-radius: .3rem;
    margin: 1.4em 0;
}

.page-body hr {
    border: 0;
    border-top: 1px solid var(--gabi-line);
    margin: 2em 0;
}

/* -------------------------------------------------------------------- modal */

.viewer-modal .modal-content {
    background: rgba(12, 11, 10, .97);
    border: 0;
}

.viewer-modal img {
    max-width: 100%;
    max-height: 82vh;
    object-fit: contain;
    margin-inline: auto;
    display: block;
}

.viewer-modal .modal-header {
    border: 0;
}

.viewer-modal .viewer-title {
    color: #f2ede8;
    letter-spacing: .03em;
    font-size: 1rem;
}

.viewer-modal .viewer-counter {
    color: rgba(242, 237, 232, .6);
    font-size: .8rem;
    letter-spacing: .08em;
    font-variant-numeric: tabular-nums; /* so "9 / 45" and "10 / 45" do not shift width */
    white-space: nowrap;
}

/* The arrows sit over the image rather than beside it, so a portrait photograph is not pushed
   into a narrow column to make room for two buttons that are mostly empty space. */
.viewer-stage {
    position: relative;
}

.viewer-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;

    /* 44px is the smallest thing a thumb reliably hits. */
    width: 44px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;

    border: 0;
    border-radius: .3rem;
    background: rgba(12, 11, 10, .55);
    color: #f2ede8;
    font-size: 2rem;
    line-height: 1;
    cursor: pointer;
    transition: background .15s ease, opacity .15s ease;

    /* Recessed until wanted. Fully opaque arrows compete with the photograph, which is the
       thing someone opened the lightbox to look at. */
    opacity: .55;
}

.viewer-nav:hover,
.viewer-nav:focus-visible {
    opacity: 1;
    background: rgba(12, 11, 10, .8);
}

.viewer-prev { left: .25rem; }
.viewer-next { right: .25rem; }

@media (min-width: 768px) {
    .viewer-prev { left: -.5rem; }
    .viewer-next { right: -.5rem; }
}

/* ------------------------------------------------------------------- footer */

.site-footer {
    border-top: 1px solid var(--gabi-line);
    font-size: .82rem;
}

.notice {
    border-left: 3px solid var(--gabi-clay);
    background: color-mix(in srgb, var(--gabi-clay) 8%, transparent);
    padding: .7rem .9rem;
    font-size: .85rem;
}

/* Bootstrap's default link blue is the one colour on the page that has nothing to do
   with ceramics. */
.breadcrumb a,
.page-body a:hover {
    color: var(--gabi-clay-dark);
    text-decoration-color: color-mix(in srgb, var(--gabi-clay) 50%, transparent);
    text-underline-offset: .2em;
}

.breadcrumb {
    --bs-breadcrumb-divider-color: var(--gabi-line);
    --bs-breadcrumb-item-active-color: var(--gabi-ink);
}
