/* style.css */
/* =============================================================================
   style.css - DCM Works Boilerplate Styles
   =============================================================================
   Responsive layout, forms, tables, dark mode, and utility classes.
   ============================================================================= */

/* =============================================================================
   1. DESIGN TOKENS / CUSTOM PROPERTIES
   =============================================================================
   Centralized color palette, font stacks, and RGB variants.
   The -rgb variants enable rgba() usage, e.g. rgba(var(--blue-rgb), .5).
   ============================================================================= */

:root {
    --headings-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, 'Helvetica Neue', Helvetica, sans-serif;
    --body-font:     -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, 'Helvetica Neue', Helvetica, sans-serif;

    /* Neutrals */
    --black:   #1A1A1A;   --black-rgb:   26, 26, 26;
    --white:   #FAFAFA;   --white-rgb:   250, 250, 250;
    --gray:    #6B7280;   --gray-rgb:    107, 114, 128;
    --silver:  #E5E7EB;   --silver-rgb:  229, 231, 235;
    --dark:    #374151;   --dark-rgb:    55, 65, 81;
    --light:   #F3F4F6;   --light-rgb:   243, 244, 246;

    /* Reds & Pinks */
    --rose:    #F43F5E;   --rose-rgb:    244, 63, 94;
    --red:     #DC2626;   --red-rgb:     220, 38, 38;
    --maroon:  #9D174D;   --maroon-rgb:  157, 23, 77;
    --pink:    #EC4899;   --pink-rgb:    236, 72, 153;

    /* Oranges */
    --orange:  #F97316;   --orange-rgb:  249, 115, 22;
    --amber:   #D97706;   --amber-rgb:   217, 119, 6;

    /* Yellows & Limes */
    --yellow:  #EAB308;   --yellow-rgb:  234, 179, 8;
    --lime:    #65A30D;   --lime-rgb:    101, 163, 13;

    /* Greens */
    --green:   #16A34A;   --green-rgb:   22, 163, 74;
    --emerald: #059669;   --emerald-rgb: 5, 150, 105;
    --olive:   #4D7C0F;   --olive-rgb:   77, 124, 15;

    /* Teals & Cyans */
    --teal:    #0D9488;   --teal-rgb:    13, 148, 136;
    --cyan:    #06B6D4;   --cyan-rgb:    6, 182, 212;
    --aqua:    #22D3EE;   --aqua-rgb:    34, 211, 238;

    /* Blues */
    --sky:     #0EA5E9;   --sky-rgb:     14, 165, 233;
    --blue:    #2563EB;   --blue-rgb:    37, 99, 235;
    --indigo:  #4F46E5;   --indigo-rgb:  79, 70, 229;
    --navy:    #1E3A5F;   --navy-rgb:    30, 58, 95;

    /* Purples & Fuchsias */
    --violet:  #7C3AED;   --violet-rgb:  124, 58, 237;
    --purple:  #9333EA;   --purple-rgb:  147, 51, 234;
    --fuchsia: #D946EF;   --fuchsia-rgb: 217, 70, 239;
}

/* =============================================================================
   2. DARK MODE
   =============================================================================
   body.dark flips black and white for a dark UI.
   The @media query respects the user's OS-level preference automatically.
   ============================================================================= */

body.dark {
    --black:  #F1F5F9;   --black-rgb:   241, 245, 249;
    --white:  #0B1121;   --white-rgb:   11, 17, 33;
    --dark:   #E2E8F0;   --dark-rgb:    226, 232, 240;
    --light:  #1A2332;   --light-rgb:   26, 35, 50;
    --silver: #334155;   --silver-rgb:  51, 65, 85;
}

@media (prefers-color-scheme: dark) {
    :root {
        --black:  #F1F5F9;   --black-rgb:   241, 245, 249;
        --white:  #0B1121;   --white-rgb:   11, 17, 33;
        --dark:   #E2E8F0;   --dark-rgb:    226, 232, 240;
        --light:  #1A2332;   --light-rgb:   26, 35, 50;
        --silver: #334155;   --silver-rgb:  51, 65, 85;
    }
}

/* =============================================================================
   3. GLOBAL RESET & BASE LAYOUT
   =============================================================================
   Use border-box so padding doesn't add to element width.
   Full-height page with zero default margin and consistent font rendering.
   ============================================================================= */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

html {
    font-size: 16px;
}

body {
    font-family: var(--body-font);
    background: var(--white);
    color: var(--black);
    line-height: 1.5;
    text-rendering: optimizeLegibility;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
}

/* =============================================================================
   4. MEDIA ELEMENTS
   =============================================================================
   Images, video, and SVG scale with their container by default.
   ============================================================================= */

img,
picture,
video,
canvas,
svg {
    display: block;
    height: auto;
    max-width: 100%;
}

/* =============================================================================
   5. FORM CONTROLS
   =============================================================================
   Reset browser defaults so inputs match the app's font and color scheme.
   Dropdown options use variables to prevent invisible text in dark mode.
   ============================================================================= */

input,
button,
textarea,
select {
    border-width: 1px;
    -webkit-tap-highlight-color: transparent;
    font: inherit;
    color: inherit;
    background: transparent;
}

select option,
select optgroup {
    background: var(--white);
    color: var(--black);
}

button,
input[type="submit"] {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
}

/* =============================================================================
   6. TYPOGRAPHY
   =============================================================================
   Responsive heading scale, consistent margins, and body text sizing.
   ============================================================================= */

h1,
h2,
h3,
h4,
h5,
h6 {
    font-family: var(--headings-font);
    font-weight: 700;
}

h1,
h2,
h3,
h4,
h5,
h6,
p {
    color: inherit;
    margin-top: 8px;
    margin-bottom: 8px;
}

h1 {
    font-size: 2rem;
    line-height: 1.2;
}

h2 {
    font-size: 1.5rem;
    line-height: 1.4;
}

h3 {
    font-size: 1.25rem;
    line-height: 1.25;
}

h4 {
    font-size: 1rem;
    line-height: 1.25;
}

h5 {
    font-size: .875rem;
    line-height: 1.25;
}

h6 {
    font-size: .8125rem;
    line-height: 1.25;
}

p {
    font-size: .95rem;
}

span {
    font-size: inherit;
}

p,
span {
    line-height: 1.5;
}

@media (min-width: 768px) {
    h1 { font-size: 3rem; }
    h2 { font-size: 2.25rem; }
    h3 { font-size: 1.5rem; }
    h4 { font-size: 1.125rem; }
    h5 { font-size: 1rem; }
    h6 { font-size: .875rem; }
    p  { font-size: 1rem; }
}

/* =============================================================================
   7. LINKS & UTILITY CLASSES
   ============================================================================= */

a {
    font-size: inherit;
    color: inherit;
    text-decoration: none;
}

.hidden {
    display: none !important;
}

@media (max-width: 767px) {
    .hidden-for-mobile { display: none !important; }
}

@media (min-width: 768px) {
    .hidden-for-desktop { display: none !important; }
}

.text-center {
    text-align: center;
}

ul.styled-list {
    margin: 0;
    padding-left: 0;
}

ul.styled-list li {
    list-style-type: none;
}

/* =============================================================================
    8. SPACING UTILITIES
   ============================================================================= */

.vertical-spacer-1 {
    padding-top: 16px;
    padding-bottom: 16px;
}

.vertical-spacer-2 {
    padding-top: 32px;
    padding-bottom: 32px;
}

.vertical-spacer-3 {
    padding-top: 64px;
    padding-bottom: 64px;
}

/* =============================================================================
   9. LAYOUT CONTAINERS
   =============================================================================
   Centered container with max-width and mobile-first padding.
   Flex row/column grid for layout composition.
   ============================================================================= */

.custom-container {
    margin-left: auto;
    margin-right: auto;
    width: 100%;
    max-width: 1200px;
    padding: 16px;
}

@media (min-width: 1440px) {
    .custom-container {
        max-width: 1440px;
    }   
}

.custom-row {
    display: flex;
    flex-wrap: wrap;
}

.custom-column {
    flex-basis: 100%;
    width: 100%;
}

@media (min-width: 768px) {
    .custom-column {
        flex-basis: auto;
        width: auto;
    }
}

.wrapper {
    padding: 16px;
}

/* =============================================================================
   10. MEDIA WRAPPER
   =============================================================================
   Maintains a 16:9 aspect ratio with object-fit cover.
   ============================================================================= */

.media-wrapper {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
}

.media-wrapper img,
.media-wrapper video {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* =============================================================================
   11. FORM STYLES
   =============================================================================
   Basic accessible form layout, full-width inputs, code blocks, and hr.
   ============================================================================= */

label {
    display: block;
    margin-bottom: 8px;
}

input[type="checkbox"] {
    margin: 0;
}

input[type="checkbox"] + label,
input[type="radio"] + label {
    display: inline-block;
}

input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
    width: 100%;
}

input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select,
textarea {
    padding: 8px 16px;
}

input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
    margin-bottom: 16px;
}

textarea {
    resize: none;
}

fieldset {
    margin: 0;
}

button::-moz-focus-inner,
input::-moz-focus-inner {
    border: 0;
    padding: 0;
}

hr {
    border: none;
    border-top: 1px solid var(--silver);
    margin: 16px 0;
}

pre {
    margin: 0;
    padding: 16px;
    white-space: pre-wrap;
    word-break: break-all;
    background: rgba(var(--silver-rgb), .25);
}

/* =============================================================================
   12. BUTTONS
   =============================================================================
   Primary button, inverted (alt) variant, hover dim effect, disabled state.
   ============================================================================= */

button,
.button {
    display: inline-block;
    background: var(--black);
    color: var(--white);
    border: solid 2px var(--black);
    padding: 8px 16px;
    font-size: .85rem;
    font-weight: 500;
    transition: opacity .25s ease;
}

button[disabled] {
    opacity: .25;
    cursor: not-allowed;
}

button:not([disabled]):hover,
.button:not([disabled]):hover {
    opacity: .5;
}

button.button-alt,
.button.button-alt {
    background: var(--white);
    color: var(--black);
}

/* =============================================================================
   13. TABLES
   =============================================================================
   Responsive table wrapper, bordered cells, zebra striping, mobile sizing.
   ============================================================================= */

.table-wrapper {
    overflow-x: auto;
}

table {
    width: 100%;
    border-collapse: collapse;
    background: var(--white);
}

table caption {
    margin-bottom: 16px;
}

th,
td {
    border: 1px solid var(--silver);
    padding: 8px;
}

th {
    background: rgba(var(--silver-rgb), .5);
    font-weight: 700;
}

td {
    font-weight: 400;
}

td.actions-col {
    white-space: nowrap;
}

tr:nth-child(even) td {
    background: rgba(var(--silver-rgb), .15);
}

@media (max-width: 767px) {
    table { font-size: .85rem; }
}

/* =============================================================================
   14. HEADER
   =============================================================================
   Site-wide header - mobile nav collapse/expand, desktop dropdown menus.
   Language switcher, logo alignment, and responsive ordering.
   ============================================================================= */

.header {
    box-shadow: 0 1px 2px rgba(var(--black-rgb), .05);
}

.header a > p {
    font-weight: 700;
    font-size: 1.75rem;
    line-height: 1.25;
    margin: 0;
}

.header .custom-container {
    padding: 12px 16px;
}

.header .custom-container > .custom-row {
    align-items: center;
    justify-content: space-between;
}

.header img {
    max-width: 160px;
}

.header li {
    flex: 0 0 100%;
    list-style-type: none;
}

.header li a {
    display: inline-block;
    position: relative;
}

.header li:not(:last-child) {
    margin-bottom: 16px;
}

.header nav > ul {
    display: flex;
    flex-flow: row wrap;
    align-items: center;
    padding: 0;
    margin: 0;
}

.header li.active > a,
.header li a:hover {
    text-decoration: underline;
    text-decoration-color: rgba(var(--black-rgb), .5);
    text-decoration-thickness: 2px;
    text-underline-offset: 8px;
}

.header.expanded .hidden-for-mobile {
    display: block !important;
}

.header .custom-column {
    width: auto;
}

.header select {
    margin: 0;
}

/* -------------------------------------------------------------------------
   Header - Mobile (< 768px)
   ------------------------------------------------------------------------- */

@media screen and (max-width: 767px) {
    .header .custom-column:first-child {
        flex: 0 0 70%;
        width: 70%;
        order: 0;
        overflow: hidden;
    }

    .header .hidden-for-desktop {
        flex: 0 0 30%;
        width: 30%;
        order: 1;
        text-align: end;
        overflow: hidden;
    }

    .header .hidden-for-mobile {
        order: 2;
        display: block !important;
        max-height: 0;
        overflow: hidden;
        transition: max-height .25s ease;
    }

    .header.expanded .custom-column.hidden-for-mobile {
        max-height: 512px;
    }

    .header .custom-column.hidden-for-mobile nav {
        padding: 16px 0;
    }

    .header li > ul {
        background: transparent;
        box-shadow: none;
        display: block !important;
        margin-top: 16px;
        min-width: auto;
        position: static;
    }
}

/* -------------------------------------------------------------------------
   Header - Desktop (>= 768px)
   ------------------------------------------------------------------------- */

@media screen and (min-width: 768px) {
    .header a > p {
        font-size: 2.5rem;
    }

    .header img {
        max-width: 200px;
    }

    .header li {
        position: relative;
        flex: 0 0 auto;
    }

    .header li:not(:last-child) {
        margin: 0;
        margin-inline-end: 16px;
    }

    .header li > ul {
        display: none;
        padding: 8px 16px;
        position: absolute;
        inset-inline-end: 0;
        min-width: 192px;
        z-index: 10;
        text-align: end;
        box-shadow:
            0 4px 0 0 rgba(0, 0, 0, .05),
            0 8px 16px 0 rgba(0, 0, 0, .1);
    }

    .header li > ul::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: var(--white);
    }

    .header li:hover > ul {
        display: block;
    }

    .header li:focus-within > ul {
        display: block;
    }

    .header li > ul > li {
        flex: 0 0 100%;
        padding: 8px 0;
        margin: 0 !important;
    }
}

/* =============================================================================
   15. FOOTER
   =============================================================================
   Responsive footer with column reordering on mobile.
   ============================================================================= */

.footer p {
    margin: 0;
}

.footer .styled-list {
    display: flex;
    flex-flow: row wrap;
}

.footer li {
    flex: 0 0 100%;
    list-style-type: none;
}

.footer li a {
    display: inline-block;
    position: relative;
}

.footer li:not(:last-child) {
    margin-bottom: 16px;
}

@media screen and (max-width: 767px) {
    .footer .custom-column:first-child { order: 2; }
    .footer .custom-column:last-child  { order: 1; margin-bottom: 32px; }
}

@media screen and (min-width: 768px) {
    .footer .custom-row { justify-content: space-between; align-items: center; }
    .footer li          { flex: 0 0 auto; }
    .footer li:not(:last-child) { margin: 0; margin-inline-end: 16px; }
}
/* theme.css */
/* =============================================================================
   theme.css - davidcostamano.pt, on top of style.css (never edit that file)
   =============================================================================
   Everything that is not the style.css base, in cascade order: 1-4 the
   look (tokens for both modes, typography, buttons, forms), 5 the page
   layout (sections, headings, cards, hero, footer), 6 the site itself.
   css.php serves style.css + this file as one gzipped request.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. CONFIG - fonts, brand, shape and the neutrals of both modes
   -------------------------------------------------------------------------- */

:root {
    /* Fonts: Noto Sans, loaded from Google Fonts by the page head, with
       the system stack behind it */
    --headings-font: 'Noto Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
    --body-font:     'Noto Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;

    /* Brand - ink by default: buttons and accents follow the text color and
       invert automatically in dark mode */
    --brand:     var(--black);
    --brand-rgb: var(--black-rgb);

    /* Shape */
    --radius:    8px;    /* controls: inputs, buttons, pills */
    --radius-lg: 12px;   /* surfaces: cards */
    --radius-xl: 20px;   /* larger surfaces get a softer corner */

    /* Hairline used for every border; flips with the mode */
    --border: rgba(var(--black-rgb), .12);

    /* The site's own colours: --accent is the one warm yellow (the only
       colour on the dark stage) with dark text on it, --accent-text the
       accent as a text colour (ink on light surfaces, where yellow would
       not read, with a yellow underline where it is a link; the yellow
       itself in dark mode), --ink the hero's near-black (dark in both
       modes, a step darker in dark mode) and --ink-deep the far end of
       its gradients */
    --accent:           #F5B301;
    --accent-rgb:       245, 179, 1;
    --on-accent:        #1E1E1E;
    --on-accent-rgb:    30, 30, 30;
    --accent-text:      #1E1E1E;
    --accent-text-rgb:  30, 30, 30;
    --ink:              #1E1E1E;
    --ink-rgb:          30, 30, 30;
    --ink-deep:         #121212;
    --on-ink:           #FFFFFF;
    --on-ink-rgb:       255, 255, 255;

    /* The studio's mark (the same dark square and indigo dot as on
       dcm-works.com) and the plates behind the employer logos: logos are
       drawn for white, so their plate stays white in dark mode too, and a
       logo drawn in white sits on a fixed black plate. None of them flip. */
    --studio-ink:       #111114;
    --studio-accent:    #6366F1;
    --logo-plate:       #FFFFFF;
    --logo-plate-dark:  #111111;

    /* The ink of every shadow; never flips */
    --shadow-rgb: 0, 0, 0;

    /* Error messages and the edge of an invalid control; flips with the
       mode */
    --error-text: #B91C1C;

    /* The top bar and the form fields: one step off the canvas and the
       cards, lighter in light mode and darker in dark mode */
    --chrome: #F3F3F3;
    --field:  #FFFFFF;

    /* Neutrals replacing the style.css defaults: soft #3B3B3B ink, an
       #F8F8F8 canvas, pure white cards, #E5E5E5 dividers */
    --black:  #3B3B3B;   --black-rgb:  59, 59, 59;
    --white:  #FFFFFF;   --white-rgb:  255, 255, 255;
    --dark:   #505050;   --dark-rgb:   80, 80, 80;
    --gray:   #616161;   --gray-rgb:   97, 97, 97;
    --silver: #E5E5E5;   --silver-rgb: 229, 229, 229;
    --light:  #F8F8F8;   --light-rgb:  248, 248, 248;
}

/* Dark mode - layered grays: #181818 chrome, a #1F1F1F canvas, #252526
   cards, #313131 fields, #2B2B2B dividers and #CCCCCC text. Keep the three
   blocks in sync: body.dark is the mode switch, the media query is the OS
   preference, body.light overrides a dark OS preference. The derived
   tokens (--brand, --border) are repeated on body because var() inside a
   custom property resolves where the property is declared. */
body.dark {
    --black:  #CCCCCC;   --black-rgb:  204, 204, 204;
    --white:  #252526;   --white-rgb:  37, 37, 38;
    --dark:   #B4B4B4;   --dark-rgb:   180, 180, 180;
    --gray:   #9D9D9D;   --gray-rgb:   157, 157, 157;
    --silver: #2B2B2B;   --silver-rgb: 43, 43, 43;
    --light:  #1F1F1F;   --light-rgb:  31, 31, 31;

    --brand:     var(--black);
    --brand-rgb: var(--black-rgb);
    --border:    rgba(var(--black-rgb), .10);

    --accent-text:     #F5B301;
    --accent-text-rgb: 245, 179, 1;
    --ink:             #141414;
    --ink-rgb:         20, 20, 20;

    --chrome: #181818;
    --field:  #313131;

    --error-text: #F87171;
}

@media (prefers-color-scheme: dark) {
    :root {
        --black:  #CCCCCC;   --black-rgb:  204, 204, 204;
        --white:  #252526;   --white-rgb:  37, 37, 38;
        --dark:   #B4B4B4;   --dark-rgb:   180, 180, 180;
        --gray:   #9D9D9D;   --gray-rgb:   157, 157, 157;
        --silver: #2B2B2B;   --silver-rgb: 43, 43, 43;
        --light:  #1F1F1F;   --light-rgb:  31, 31, 31;

        --brand:     var(--black);
        --brand-rgb: var(--black-rgb);
        --border:    rgba(var(--black-rgb), .10);

        --accent-text:     #F5B301;
        --accent-text-rgb: 245, 179, 1;
        --ink:             #141414;
        --ink-rgb:         20, 20, 20;

        --chrome: #181818;
        --field:  #313131;

        --error-text: #F87171;
    }
}

/* Explicit light mode: the page opens with body.light (index.php), so it
   is light until the visitor picks dark; the values mirror :root */
body.light {
    --black:  #3B3B3B;   --black-rgb:  59, 59, 59;
    --white:  #FFFFFF;   --white-rgb:  255, 255, 255;
    --dark:   #505050;   --dark-rgb:   80, 80, 80;
    --gray:   #616161;   --gray-rgb:   97, 97, 97;
    --silver: #E5E5E5;   --silver-rgb: 229, 229, 229;
    --light:  #F8F8F8;   --light-rgb:  248, 248, 248;

    --brand:     var(--black);
    --brand-rgb: var(--black-rgb);
    --border:    rgba(var(--black-rgb), .12);

    --accent-text:     #1E1E1E;
    --accent-text-rgb: 30, 30, 30;
    --ink:             #1E1E1E;
    --ink-rgb:         30, 30, 30;

    --chrome: #F3F3F3;
    --field:  #FFFFFF;

    --error-text: #B91C1C;
}

/* -----------------------------------------------------------------------------
   2. TYPOGRAPHY
   -------------------------------------------------------------------------- */

h1, h2, h3 {
    letter-spacing: -0.01em;
}

body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-optical-sizing: auto;
}

/* Vertical rhythm (style.css only gives text blocks 8px) */
h1, h2, h3, h4, h5, h6 {
    margin-bottom: 16px;
}

p {
    margin-bottom: 12px;
}

/* -----------------------------------------------------------------------------
   3. BUTTONS - solid ink, hairline border, layered hover instead of the
   style.css opacity fade
   -------------------------------------------------------------------------- */

button,
.button {
    background: var(--brand);
    border: 1px solid var(--brand);
    color: var(--white); /* inverts with --brand, so it works in both modes */
    padding: 8px 16px;
    border-radius: var(--radius);
    letter-spacing: .01em;
    transition: background-color .15s ease, border-color .15s ease;
}

/* A translucent --white veil lightens the ink button in light mode and
   dims the inverted button in dark mode - one rule for both */
button:not([disabled]):hover,
.button:not([disabled]):hover {
    opacity: 1;
    background-image: linear-gradient(rgba(var(--white-rgb), .14), rgba(var(--white-rgb), .14));
}

button:focus-visible,
.button:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

/* Secondary: quiet surface button with a hairline edge */
button.button-alt,
.button.button-alt {
    background: var(--white);
    border-color: rgba(var(--black-rgb), .15);
    color: var(--black);
}

button.button-alt:not([disabled]):hover,
.button.button-alt:not([disabled]):hover {
    background-image: linear-gradient(rgba(var(--black-rgb), .04), rgba(var(--black-rgb), .04));
    border-color: rgba(var(--black-rgb), .3);
}

/* -----------------------------------------------------------------------------
   4. SURFACES AND FORMS
   -------------------------------------------------------------------------- */

/* Soft canvas behind the content; cards sit on --white, the top bar on
   --chrome. All three flip in dark mode. */
body {
    background: var(--light);
}

.header {
    background: var(--chrome);
}

.footer p {
    color: var(--gray);
    font-size: .85rem;
}

.custom-container > h1 {
    font-size: 1.75rem;
    line-height: 1.25;
    letter-spacing: -0.02em;
    margin-bottom: 16px;
}

.custom-container > h3 {
    margin-bottom: 12px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--dark);
}

/* site.js sets .input-invalid on a field that fails validation */
/* The input selector repeats the :not() list of the input rule below, so
   the red edge outweighs its hairline border */
input.input-invalid:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select.input-invalid,
textarea.input-invalid {
    border-color: var(--error-text);
}

form + p,
button + p,
.button + p {
    margin-top: 16px;
}

.wrapper > :last-child {
    margin-bottom: 0;
}

/* Inputs: hairline border, rounded, ink focus ring */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select,
textarea {
    border: 1px solid rgba(var(--black-rgb), .14);
    border-radius: var(--radius);
    background: var(--field);
    transition: border-color .15s ease, box-shadow .15s ease;
}

input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(var(--brand-rgb), .12);
}

pre {
    border-radius: var(--radius);
}

/* Button rows: a wrapping flex row where each action spaces itself with
   sibling margins, 8px apart in both directions */
.form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 16px;
}

.form-actions > * {
    margin-inline-end: 8px;
    margin-top: 8px;
}

/* -----------------------------------------------------------------------------
   5. PAGE - smooth anchor scrolling, sections clear the sticky header
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
    html {
        scroll-behavior: smooth;
    }
}

main > section {
    padding-top: 64px;
    padding-bottom: 64px;
    scroll-margin-top: 72px;
}

main > section + section {
    border-top: 1px solid var(--border);
}

/* Small uppercase label above a heading */
.eyebrow {
    margin: 0 0 12px;
    color: var(--brand);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* Muted intro paragraph under a heading */
.lead {
    color: var(--gray);
    font-size: 1.05rem;
    line-height: 1.6;
}

/* Section intro block: eyebrow, h2, lead - kept narrow for reading */
.section-heading {
    max-width: 640px;
    margin-bottom: 40px;
}

.section-heading h2 {
    margin-top: 0;
    margin-bottom: 12px;
    line-height: 1.2;
}

.section-heading .lead {
    margin-bottom: 0;
}

/* Card grid - no gap. Row > .custom-column > .inner-column > content:
   the column only takes its exact share of the row (style.css stacks it
   at 100% on mobile, the media queries below take it to 50% and
   33.333%) and carries no padding; the .inner-column pads by 8px, half
   of the 16px gutter on every side, and the row's -8px margin takes the
   outer half back so the content sits flush with the container. Inside
   goes a .wrapper card or plain content. Column and inner column are
   flex boxes, so every card in a row fills the same height. */
.card-grid {
    margin: -8px;
}

.card-grid > .custom-column {
    display: flex;
}

.card-grid > .custom-column > .inner-column {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px;
}

.card-grid > .custom-column > .inner-column > .wrapper {
    flex: 1 1 auto;
    min-width: 0;
    padding: 24px;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--white);
    box-shadow: 0 1px 2px rgba(var(--shadow-rgb), .04);
}

.card-grid h3 {
    margin-top: 0;
    margin-bottom: 8px;
    font-size: 1.1rem;
}

.card-grid p {
    margin: 0;
    color: var(--gray);
    font-size: .95rem;
}

@media (min-width: 768px) {
    .card-grid > .custom-column {
        flex: 1 1 50%;
    }
}

@media (min-width: 1024px) {
    .card-grid > .custom-column {
        flex-basis: 33.333%;
    }
}

/* Small category pill */
.tag {
    display: inline-block;
    margin-bottom: 12px;
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--gray);
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
}

.tag-infra {
    border-color: transparent;
    background: rgba(var(--brand-rgb), .08);
    color: var(--brand);
}

/* Header: the style.css top bar, made sticky with a hairline */
.header {
    position: sticky;
    top: 0;
    z-index: 30;
    border-bottom: 1px solid var(--border);
}

.header nav li a {
    color: var(--dark);
    font-size: .9rem;
    font-weight: 500;
}

/* #hero: copy beside a visual, stacked on mobile */
#hero {
    padding-top: 80px;
}

#hero .custom-row {
    align-items: center;
}

#hero h1 {
    margin-top: 0;
    font-size: 2.1rem;
    line-height: 1.1;
    letter-spacing: -.02em;
}

@media (min-width: 768px) {
    #hero h1 {
        font-size: 2.5rem;
    }
}

@media (min-width: 1024px) {
    #hero h1 {
        font-size: 3.25rem;
    }
}

#hero .lead {
    max-width: 560px;
    margin-bottom: 24px;
}

#hero .form-actions {
    margin-top: 0;
}

/* Footer: the style.css two-column footer, quiet links */
.footer {
    padding: 32px 0;
    border-top: 1px solid var(--border);
}

.footer .styled-list a {
    color: var(--gray);
    font-size: .85rem;
    transition: color .15s ease;
}

.footer .styled-list a:hover {
    color: var(--black);
}

/* =============================================================================
   6. SITE
   =============================================================================
   Every colour comes from the tokens of section 1 (the neutrals, and the
   site's --accent, --accent-text and --ink), which flip with the mode
   switch.

   Motion: sections and cards carry .reveal and fade in when site.js sees
   them enter the viewport; numbers count up. All of it is switched off
   under prefers-reduced-motion at the end.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   Shared pieces
   -------------------------------------------------------------------------- */

button,
.button {
    font-weight: 600;
    transition: background-color .2s ease, border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}

.button:not([disabled]):hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 24px -12px rgba(var(--black-rgb), .5);
}

/* Accent button: the loud one, for every call to action, the same yellow
   with the same glow on every surface */
.button.button-accent {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
    box-shadow: 0 16px 32px -12px rgba(var(--accent-rgb), .6);
}

.button.button-accent:not([disabled]):hover {
    background-image: linear-gradient(rgba(var(--on-ink-rgb), .12), rgba(var(--on-ink-rgb), .12));
    box-shadow: 0 20px 40px -12px rgba(var(--accent-rgb), .7);
}

/* Ghost button: translucent, sits next to the accent one on the ink stage */
.button.button-ghost {
    background: rgba(var(--on-ink-rgb), .1);
    border-color: rgba(var(--on-ink-rgb), .35);
    color: var(--on-ink);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.button.button-ghost:not([disabled]):hover {
    background: rgba(var(--on-ink-rgb), .18);
    border-color: rgba(var(--on-ink-rgb), .6);
    box-shadow: none;
}

.button-lg {
    padding: 14px 24px;
    font-size: 1rem;
}

/* Sections: generous rhythm, backgrounds instead of hairlines */
main > section {
    padding-top: 56px;
    padding-bottom: 56px;
}

@media (min-width: 768px) {
    main > section {
        padding-top: 96px;
        padding-bottom: 96px;
    }
}

main > section + section {
    border-top: 0;
}

#sobre,
#percurso,
#contacto {
    background: var(--white);
}

#competencias,
#projetos {
    background: var(--light);
}

.section-heading {
    max-width: 720px;
    margin-bottom: 32px;
}

@media (min-width: 768px) {
    .section-heading {
        margin-bottom: 56px;
    }
}

.section-heading h2,
.about-copy h2,
.contact-copy h2 {
    font-size: 2rem;
    line-height: 1.08;
    letter-spacing: -.025em;
}

@media (min-width: 768px) {
    .section-heading h2,
    .about-copy h2,
    .contact-copy h2 {
        font-size: 2.15rem;
    }
}

@media (min-width: 1024px) {
    .section-heading h2,
    .about-copy h2,
    .contact-copy h2 {
        font-size: 2.75rem;
    }
}

@media (min-width: 1280px) {
    .section-heading h2,
    .about-copy h2,
    .contact-copy h2 {
        font-size: 3rem;
    }
}

.section-heading .lead,
.lead {
    font-size: 1.15rem;
    line-height: 1.65;
}

/* Eyebrow: a pill with an accent dot. The line box is the font size so
   the caps sit centred between the paddings, and the end padding gives
   back the letter-spacing that trails the last letter. */
.eyebrow {
    display: inline-flex;
    align-items: center;
    margin-bottom: 20px;
    padding: 9px 14px 7px;
    padding-inline-end: calc(14px - .1em);
    border-radius: 999px;
    background: rgba(var(--accent-rgb), .16);
    color: var(--accent-text);
    font-size: .72rem;
    line-height: 1;
    letter-spacing: .1em;
}

.eyebrow::before {
    content: '';
    position: relative;
    top: -1px;
    width: 8px;
    height: 8px;
    margin-inline-end: 8px;
    border-radius: 50%;
    background: var(--accent);
}

.micro-label {
    display: block;
    margin-bottom: 8px;
    color: var(--gray);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* Card grids: softer corners, hover lift */
.card-grid > .custom-column > .inner-column > .wrapper {
    position: relative;
    padding: 24px;
    border-radius: var(--radius-xl);
    transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}

@media (min-width: 768px) {
    .card-grid > .custom-column > .inner-column > .wrapper {
        padding: 32px;
    }
}

.card-grid > .custom-column > .inner-column > .wrapper:hover {
    transform: translateY(-6px);
    border-color: rgba(var(--accent-rgb), .6);
    box-shadow: 0 32px 48px -32px rgba(var(--ink-rgb), .35);
}

.card-grid h3 {
    font-size: 1.25rem;
    letter-spacing: -.01em;
}

/* Scroll reveal: hidden until site.js marks the element visible, with a
   small stagger between siblings */
.reveal {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity .8s ease, transform .8s cubic-bezier(.2, .7, .2, 1);
}

.reveal.is-visible {
    opacity: 1;
    transform: none;
}

.reveal:nth-child(2) { transition-delay: .1s; }
.reveal:nth-child(3) { transition-delay: .2s; }
.reveal:nth-child(4) { transition-delay: .3s; }
.reveal:nth-child(5) { transition-delay: .4s; }
.reveal:nth-child(6) { transition-delay: .5s; }

@keyframes rise {
    from {
        opacity: 0;
        transform: translateY(32px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes wave {
    0%, 60%, 100% {
        transform: rotate(0);
    }
    10%, 30% {
        transform: rotate(16deg);
    }
    20%, 40% {
        transform: rotate(-8deg);
    }
    50% {
        transform: rotate(10deg);
    }
}

@keyframes float {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-12px);
    }
}

@keyframes glow {
    0%, 100% {
        opacity: .7;
        transform: translateX(-50%) scale(1);
    }
    50% {
        opacity: 1;
        transform: translateX(-50%) scale(1.12);
    }
}

@keyframes twinkle {
    0%, 100% {
        opacity: .35;
    }
    50% {
        opacity: .9;
    }
}

@keyframes ticker {
    from {
        transform: translateX(0);
    }
    to {
        transform: translateX(-50%);
    }
}

/* -----------------------------------------------------------------------------
   Header: frosted bar, wordmark, section links; a soft shadow once the
   page has scrolled is its only motion
   -------------------------------------------------------------------------- */

.header {
    background: rgba(var(--white-rgb), .82);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: none;
    transition: box-shadow .3s ease;
}

.header.is-scrolled {
    box-shadow: 0 8px 32px -16px rgba(var(--ink-rgb), .25);
}

/* The row never wraps, and the brand column is itself a flex box so the
   brand sits on the row's centre line instead of on a text baseline. On
   phones the brand column takes whatever the buttons leave. */
.header .custom-container > .custom-row {
    flex-wrap: nowrap;
}

.header .custom-container > .custom-row > .custom-column:first-child {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    width: auto;
    min-width: 0;
}

@media (min-width: 768px) {
    .header .custom-container > .custom-row > .custom-column:first-child {
        flex: 0 1 auto;
    }
}

.site-brand {
    display: inline-flex;
    align-items: center;
    color: inherit;
    transition: opacity .2s ease;
}

.site-brand:hover {
    opacity: .75;
}

.wordmark {
    display: inline-flex;
    align-items: center;
}

/* Flex centres the font's line box, which sits the capitals 0.75px high
   in the 32px mark from 768px; the 1px top padding there is an optical
   correction (the 28px mark on phones is already centred) */
.wordmark-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    margin-inline-end: 8px;
    border-radius: 8px;
    background: var(--ink);
    color: var(--accent);
    font-size: .58rem;
    font-weight: 800;
    letter-spacing: -.02em;
}

@media (min-width: 768px) {
    .wordmark-mark {
        width: 32px;
        height: 32px;
        padding-top: 1px;
        margin-inline-end: 10px;
        border-radius: 9px;
        font-size: .66rem;
    }
}

.wordmark-name {
    font-family: var(--headings-font);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: -.01em;
    white-space: nowrap;
}

@media (min-width: 768px) {
    .wordmark-name {
        font-size: 1.1rem;
    }
}

/* The section links: gone on phones (style.css would fold them into a
   collapsible block), centred in the bar from 768px */
.header .custom-column.header-nav {
    display: none !important;
}

@media (min-width: 768px) {
    .header .custom-column.header-nav {
        display: block !important;
    }
}

.header .header-nav {
    flex: 1 1 auto;
    text-align: center;
}

.header .header-nav nav > ul {
    justify-content: center;
}

.header .header-nav li a {
    padding: 8px 12px;
    border-radius: 999px;
    color: var(--dark);
    font-size: .9rem;
    font-weight: 500;
    transition: background-color .2s ease, color .2s ease;
}

.header .header-nav li a:hover {
    background: rgba(var(--black-rgb), .05);
    color: var(--black);
    text-decoration: none;
}

.header .header-nav li:not(:last-child) {
    margin-inline-end: 4px;
}

/* The switches and the button keep their one line on phones */
.header .header-cta {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: flex-end;
    width: auto;
    margin-inline-start: 12px;
}

@media (min-width: 768px) {
    .header .header-cta {
        flex: 0 1 auto;
        margin-inline-start: 0;
    }
}

.header .header-cta .button {
    padding: 8px 12px;
    font-size: .75rem;
    white-space: nowrap;
}

@media (min-width: 768px) {
    .header .header-cta .button {
        padding: 8px 16px;
        font-size: .85rem;
        white-space: normal;
    }
}

/* The header button carries a full and a short label; small phones show
   the short one so the row fits on one line */
.header .label-short {
    display: none;
}

/* Language switch: a small pill with the other language's code */
.header .lang-switch {
    display: inline-flex;
    align-items: center;
    height: 36px;
    margin-inline-end: 8px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: rgba(var(--black-rgb), .05);
    color: var(--black);
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .06em;
    transition: background-color .2s ease, border-color .2s ease;
}

@media (min-width: 768px) {
    .header .lang-switch {
        height: 40px;
        margin-inline-end: 12px;
        padding: 0 14px;
    }
}

.header .lang-switch:hover {
    background: rgba(var(--black-rgb), .1);
    border-color: rgba(var(--black-rgb), .3);
    text-decoration: none;
}

/* Light / dark switch: a round icon button showing the mode it leads to */
.header .mode-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    margin-inline-end: 8px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: rgba(var(--black-rgb), .05);
    color: var(--black);
    transition: background-color .2s ease, border-color .2s ease;
}

@media (min-width: 768px) {
    .header .mode-toggle {
        width: 40px;
        height: 40px;
        margin-inline-end: 12px;
    }
}

.header .mode-toggle:not([disabled]):hover {
    background: rgba(var(--black-rgb), .1);
    background-image: none;
    border-color: rgba(var(--black-rgb), .3);
}

.mode-toggle svg {
    width: 18px;
    height: 18px;
}

body.light .mode-toggle .icon-sun,
body.dark .mode-toggle .icon-moon {
    display: none;
}

/* Small phones (under 480px): the short button label, smaller switches,
   and the mark alone (the name is long) */
@media (max-width: 479px) {
    .header .label-full {
        display: none;
    }

    .header .label-short {
        display: inline;
    }

    .header .mode-toggle {
        width: 32px;
        height: 32px;
        margin-inline-end: 6px;
    }

    .header .mode-toggle svg {
        width: 16px;
        height: 16px;
    }

    .header .lang-switch {
        height: 32px;
        margin-inline-end: 6px;
        padding: 0 9px;
        font-size: .75rem;
    }

    .header .header-cta .button {
        padding: 8px 10px;
    }

    .wordmark-name {
        display: none;
    }
}

/* -----------------------------------------------------------------------------
   Hero: the dark stage from the earlier site, the greeting, the portrait
   and the skyline along the bottom
   -------------------------------------------------------------------------- */

/* The stage ends in the strip's colour, so the portrait's cut edge sits
   on one continuous dark surface */
#hero.site-hero {
    position: relative;
    overflow: hidden;
    padding-top: 48px;
    padding-bottom: 96px;
    background:
        radial-gradient(800px 500px at 100% 0%, rgba(var(--accent-rgb), .18), transparent 65%),
        linear-gradient(180deg, var(--ink) 0%, var(--ink-deep) 100%);
    color: var(--on-ink);
}

@media (min-width: 768px) {
    #hero.site-hero {
        padding-top: 96px;
        padding-bottom: 112px;
    }
}

.site-hero .custom-container {
    position: relative;
    z-index: 2;
}

/* The portrait stands on the bottom edge of the hero, so the row aligns
   to the bottom and the portrait column reaches through the padding
   (written with the id to outrank section 5, which centres #hero rows) */
#hero.site-hero .custom-row {
    align-items: flex-end;
}

.hero-copy > * {
    animation: rise .9s cubic-bezier(.2, .7, .2, 1) both;
}

.hero-copy > :nth-child(2) { animation-delay: .1s; }
.hero-copy > :nth-child(3) { animation-delay: .2s; }
.hero-copy > :nth-child(4) { animation-delay: .3s; }
.hero-copy > :nth-child(5) { animation-delay: .4s; }

/* A faint field of stars twinkling behind the hero */
.hero-stars {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background:
        radial-gradient(rgba(var(--accent-rgb), .9) 1px, transparent 1.5px) 12px 40px / 260px 180px,
        radial-gradient(rgba(var(--on-ink-rgb), .8) 1px, transparent 1.5px) 140px 110px / 320px 240px,
        radial-gradient(rgba(var(--on-ink-rgb), .5) 1px, transparent 1.5px) 60px 200px / 200px 300px;
    animation: twinkle 4s ease-in-out infinite;
    pointer-events: none;
}

.hero-greeting {
    display: flex;
    align-items: center;
    margin: 0 0 8px;
    color: var(--accent);
    font-family: var(--headings-font);
    font-size: 3rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.03em;
}

@media (min-width: 768px) {
    .hero-greeting {
        font-size: 3.9rem;
    }
}

@media (min-width: 1024px) {
    .hero-greeting {
        font-size: 5.05rem;
    }
}

@media (min-width: 1280px) {
    .hero-greeting {
        font-size: 5.5rem;
    }
}

/* The waving hand, pivoting at the wrist */
.wave {
    display: inline-block;
    margin-inline-start: .2em;
    font-size: .8em;
    transform-origin: 70% 70%;
    animation: wave 2.6s ease-in-out .8s infinite;
}

/* "Também sou" and the role that rotates through the list */
.hero-roles {
    margin: 0 0 20px;
    font-size: 1.1rem;
    color: rgba(var(--on-ink-rgb), .7);
}

.hero-role {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 8px;
    background: rgba(var(--accent-rgb), .16);
    color: var(--accent);
    font-weight: 700;
    transition: opacity .35s ease, transform .35s ease;
}

.hero-role.is-out {
    opacity: 0;
    transform: translateY(8px);
}

#hero.site-hero h1 {
    margin: 0 0 20px;
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.02em;
}

@media (min-width: 768px) {
    #hero.site-hero h1 {
        font-size: 2rem;
    }
}

@media (min-width: 1024px) {
    #hero.site-hero h1 {
        font-size: 2.6rem;
    }
}

@media (min-width: 1280px) {
    #hero.site-hero h1 {
        font-size: 2.9rem;
    }
}

.hero-intro {
    font-weight: 400;
    color: rgba(var(--on-ink-rgb), .75);
}

.hero-tagline {
    margin: 0 0 20px;
    font-size: 1.25rem;
    line-height: 1.5;
    color: rgba(var(--on-ink-rgb), .85);
}

.hero-tagline strong {
    color: var(--on-ink);
    font-weight: 700;
    box-shadow: inset 0 -.45em 0 rgba(var(--accent-rgb), .35);
}

#hero.site-hero .lead {
    max-width: 560px;
    margin-bottom: 32px;
    color: rgba(var(--on-ink-rgb), .72);
}

/* The negative margin swallows the hero's bottom padding (96px on
   phones) plus the container's own 16px, so the portrait's bottom edge
   is the hero's bottom edge, flush with the strip below */
.hero-portrait {
    margin-top: 40px;
    margin-bottom: -112px;
}

/* The cut-out portrait from the earlier site, standing in front of a
   soft accent glow, its shoulders running into the strip below. A block,
   not an inline box, so no line height opens a gap under it. */
.portrait-frame {
    position: relative;
    display: block;
    animation: rise 1s .3s cubic-bezier(.2, .7, .2, 1) both;
}

.portrait-frame::before {
    content: '';
    position: absolute;
    top: 8%;
    left: 50%;
    width: 88%;
    padding-top: 88%;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(var(--accent-rgb), .55), rgba(var(--accent-rgb), 0) 70%);
    transform: translateX(-50%);
    animation: glow 5s ease-in-out infinite;
}

.portrait-frame img {
    position: relative;
    display: block;
    width: 100%;
    max-width: 300px;
    margin: 0 auto;
    filter: drop-shadow(0 24px 40px rgba(var(--shadow-rgb), .6));
}

@media (min-width: 768px) {
    .portrait-frame img {
        max-width: 560px;
    }
}

/* The technology strip: an ink band whose list scrolls without end */
.ticker {
    overflow: hidden;
    padding: 16px 0;
    background: var(--ink-deep);
}

.ticker-track {
    display: flex;
    width: max-content;
    margin: 0;
    padding: 0;
    list-style: none;
    animation: ticker 40s linear infinite;
}

.ticker:hover .ticker-track {
    animation-play-state: paused;
}

.ticker-track li {
    display: inline-flex;
    align-items: center;
    padding: 0 32px;
    color: rgba(var(--on-ink-rgb), .75);
    font-family: var(--headings-font);
    font-size: .9rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.ticker-track li::before {
    content: '';
    width: 6px;
    height: 6px;
    margin-inline-end: 32px;
    border-radius: 50%;
    background: var(--accent);
}

/* The numbers in a band of their own under the technology strip, four
   across on the same dark surface (yellow on white would not read),
   separated by hairlines */
.facts-band {
    padding: 24px 0;
    background: var(--ink-deep);
    border-top: 1px solid rgba(var(--on-ink-rgb), .08);
    color: var(--on-ink);
}

@media (min-width: 768px) {
    .facts-band {
        padding: 40px 0;
    }
}

.facts {
    display: flex;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Two by two on phones, four across from 768px */
.facts li {
    flex: 0 0 50%;
    min-width: 0;
    margin-bottom: 20px;
    padding: 0 12px 0 0;
}

@media (min-width: 768px) {
    .facts li {
        flex: 1 1 0;
        margin-bottom: 0;
        padding: 0 24px;
        border-inline-start: 1px solid rgba(var(--on-ink-rgb), .15);
    }
}

.facts li:first-child {
    padding-inline-start: 0;
    border-inline-start: 0;
}

.facts li:nth-child(n+3) {
    margin-bottom: 0;
}

/* The numbers wear the same bright accent as the skill indices */
.facts strong {
    display: block;
    margin-bottom: 4px;
    color: var(--accent);
    font-family: var(--headings-font);
    font-size: 1.9rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.03em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

@media (min-width: 768px) {
    .facts strong {
        font-size: 2.25rem;
    }
}

.facts strong span {
    color: inherit;
    font-size: inherit;
}

.facts li > span {
    display: block;
    color: rgba(var(--on-ink-rgb), .75);
    font-size: .9rem;
}

/* The skyline silhouette behind the portrait, a quiet grey on the dark
   stage as on the earlier site; the portrait stands in front of it and
   runs into the technology strip below */
.hero-skyline {
    position: absolute;
    bottom: 0;
    left: 0;
    z-index: 0;
    width: 100%;
    height: 56px;
    fill: rgba(var(--on-ink-rgb), .1);
}

@media (min-width: 768px) {
    .hero-skyline {
        height: 96px;
    }

    /* Hero bottom padding (112px) plus the container's 16px */
    .hero-portrait {
        margin-bottom: -128px;
    }
}

/* The copy and the portrait stay stacked on tablets and sit side by side
   from 1024px */
@media (min-width: 768px) {
    .site-hero .hero-copy,
    .hero-portrait {
        flex: 1 1 100%;
    }

    .site-hero .hero-copy {
        min-width: 0;
    }
}

@media (min-width: 1024px) {
    .site-hero .hero-copy {
        flex: 1.25 1 0;
        padding-inline-end: 48px;
    }

    .hero-portrait {
        flex: 1 1 0;
        min-width: 0;
        margin-top: 0;
    }
}

/* -----------------------------------------------------------------------------
   About: the copy on the left, the studio card on the right
   -------------------------------------------------------------------------- */

/* Stacked up to 1024px, side by side from there */
.about-row {
    display: block;
}

@media (min-width: 1024px) {
    .about-row {
        display: flex;
        align-items: flex-start;
    }
}

.about-copy {
    flex: 1 1 0;
    min-width: 0;
    margin-bottom: 32px;
}

@media (min-width: 1024px) {
    .about-copy {
        margin-bottom: 0;
        padding-inline-end: 64px;
    }
}

.about-copy .lead {
    max-width: 640px;
}

.studio-card {
    flex: 0 0 380px;
    padding: 24px 20px;
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    background: var(--light);
}

@media (min-width: 768px) {
    .studio-card {
        padding: 32px;
    }
}

.studio-name {
    display: flex;
    align-items: center;
    margin: 0 0 12px;
    font-family: var(--headings-font);
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -.01em;
}

/* The studio's mark: the same dark square and dot as on dcm-works.com */
.studio-mark {
    position: relative;
    display: inline-block;
    width: 28px;
    height: 28px;
    margin-inline-end: 10px;
    border-radius: 8px;
    background: var(--studio-ink);
}

/* The dot, centred on the mark: (28px - 10px) / 2 from the top and the
   start */
.studio-mark::after {
    content: '';
    position: absolute;
    top: 9px;
    left: 9px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--studio-accent);
}

.studio-card p {
    color: var(--dark);
    line-height: 1.6;
}

.studio-card .form-actions {
    align-items: center;
}

.studio-link {
    color: var(--accent-text);
    font-size: .9rem;
    font-weight: 700;
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

.studio-link:hover {
    text-decoration-color: var(--accent-text);
}

/* -----------------------------------------------------------------------------
   Skills: cards with a faded index
   -------------------------------------------------------------------------- */

.skill-card {
    overflow: hidden;
}

.skill-index {
    position: absolute;
    top: 12px;
    inset-inline-end: 20px;
    color: rgba(var(--accent-rgb), .3);
    font-family: var(--headings-font);
    font-size: 4rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.04em;
    pointer-events: none;
}

.skill-card h3 {
    position: relative;
    padding-top: 8px;
}

.skill-card h3::before {
    content: '';
    display: block;
    width: 32px;
    height: 4px;
    margin-bottom: 16px;
    border-radius: 2px;
    background: var(--accent);
}

/* -----------------------------------------------------------------------------
   Career: a vertical timeline with the company logos
   -------------------------------------------------------------------------- */

.job-list {
    position: relative;
    max-width: 800px;
}

.job {
    position: relative;
    display: flex;
    align-items: flex-start;
    padding-bottom: 40px;
}

/* The rail that joins the stops draws itself downwards as each stop is
   revealed */
.job::before {
    content: '';
    position: absolute;
    top: 56px;
    inset-inline-start: 27px;
    width: 2px;
    height: calc(100% - 56px);
    background: linear-gradient(180deg, var(--accent), rgba(var(--black-rgb), .1));
    transform: scaleY(0);
    transform-origin: 50% 0;
    transition: transform .9s .4s cubic-bezier(.2, .7, .2, 1);
}

@media (min-width: 768px) {
    .job::before {
        top: 72px;
        inset-inline-start: 39px;
        height: calc(100% - 72px);
    }
}

.job.is-visible::before {
    transform: scaleY(1);
}

.job:last-child::before {
    display: none;
}

/* The tile is a plate in the logo's own world, not the site's: logos are
   drawn for white, so the plate (--logo-plate) stays white in dark mode
   too. Whatever the file has behind it, transparent or not, the logo
   reads the same in both modes. */
.job-logo {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 56px;
    width: 56px;
    height: 56px;
    margin-inline-end: 16px;
    overflow: hidden;
    border: 1px solid rgba(var(--ink-rgb), .12);
    border-radius: 14px;
    background: var(--logo-plate);
    box-shadow: 0 16px 32px -20px rgba(var(--ink-rgb), .4);
}

@media (min-width: 768px) {
    .job-logo {
        flex-basis: 80px;
        width: 80px;
        height: 80px;
        margin-inline-end: 28px;
        border-radius: 20px;
    }
}

/* The logos are wide images; they sit whole inside the tile */
.job-logo img {
    width: 100%;
    height: 100%;
    padding: 10px;
    object-fit: contain;
}

/* The one exception: a logo drawn in white sits on a fixed black plate
   ("logoDark": true in the JSON), again the same in both modes */
.job-logo-dark {
    background: var(--logo-plate-dark);
    border-color: var(--logo-plate-dark);
}

.job-monogram {
    background: var(--ink);
    color: var(--accent);
    font-family: var(--headings-font);
    font-size: 1.75rem;
    font-weight: 800;
}

.job-body {
    flex: 1 1 0;
    min-width: 0;
}

@media (min-width: 768px) {
    .job-body {
        padding-top: 8px;
    }
}

.job-period {
    display: inline-block;
    margin-bottom: 8px;
    padding: 4px 12px;
    border-radius: 999px;
    background: rgba(var(--accent-rgb), .16);
    color: var(--accent-text);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.job-body h3 {
    margin: 0 0 4px;
    font-size: 1.35rem;
    letter-spacing: -.01em;
}

.job-company {
    margin: 0 0 8px;
    font-weight: 600;
}

.job-company a {
    color: var(--accent-text);
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

.job-company a:hover {
    text-decoration-color: var(--accent-text);
}

.job-body p:last-child {
    margin: 0;
    color: var(--gray);
    line-height: 1.6;
}

/* -----------------------------------------------------------------------------
   Projects: cards with an image on top
   -------------------------------------------------------------------------- */

/* A project card keeps its column width even when it is the only one. It
   has no padding at any width: the image runs to the card's edges and the
   tag, title, text and link carry their own 24px margins */
.card-grid > .custom-column > .inner-column > .project-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
}

@media (min-width: 768px) {
    .project-grid > .custom-column {
        flex: 0 1 50%;
    }
}

@media (min-width: 1024px) {
    .project-grid > .custom-column {
        flex-basis: 33.333%;
    }
}

.project-image {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    border-bottom: 1px solid var(--border);
}

.project-placeholder {
    background: linear-gradient(160deg, var(--ink), var(--ink-deep));
    color: var(--accent);
    font-family: var(--headings-font);
    font-size: 4rem;
    font-weight: 800;
}

.project-card .tag {
    align-self: flex-start;
    margin: 24px 24px 12px;
    border-color: transparent;
    background: rgba(var(--accent-rgb), .16);
    color: var(--accent-text);
}

.card-grid .project-card h3 {
    margin: 0 24px 8px;
}

.card-grid .project-card p {
    flex: 1 1 auto;
    margin: 0 24px;
}

/* A project's running offer (a launch code): a highlighted line under the
   text, its code in bold */
.card-grid .project-card p.project-offer {
    flex: 0 0 auto;
    margin: 16px 24px 0;
    padding: 8px 12px;
    border-inline-start: 4px solid var(--accent);
    border-radius: var(--radius);
    background: rgba(var(--accent-rgb), .12);
    font-size: .9rem;
}

/* The link is the card's last child; this selector outranks
   ".wrapper > :last-child", which would take its bottom margin away */
.project-card > .project-link {
    align-self: flex-start;
    display: inline-block;
    margin: 20px 24px 24px;
    color: var(--accent-text);
    font-size: .9rem;
    font-weight: 700;
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

/* The whole card is clickable: the link's layer stretches over the card
   (the .wrapper is position: relative), so it stays the card's one link */
.project-card > .project-link::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border-radius: var(--radius-xl);
}

.project-card > .project-link:focus-visible {
    outline: none;
}

.project-card:has(.project-link:focus-visible) {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* -----------------------------------------------------------------------------
   Blog: post cards on the home page and on the list, and the article
   -------------------------------------------------------------------------- */

#blog {
    background: var(--white);
}

/* The message on a blog with no posts yet, in the card text size */
.blog-empty {
    margin: 0;
    font-size: .95rem;
}

.card-grid > .custom-column > .inner-column > .post-card {
    display: flex;
    flex-direction: column;
    color: var(--black);
}

.post-date {
    display: block;
    margin-bottom: 12px;
    color: var(--gray);
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.card-grid .post-card h3 {
    margin-bottom: 12px;
    font-size: 1.25rem;
    line-height: 1.3;
}

.card-grid .post-card p {
    flex: 1 1 auto;
    line-height: 1.6;
}

.post-read {
    margin-top: 20px;
    color: var(--accent-text);
    font-size: .9rem;
    font-weight: 700;
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

.section-more {
    margin: 40px 0 0;
    text-align: center;
}

/* The blog list page: the heading is an h1 at the section's size */
.blog-page {
    padding-top: 64px;
}

.blog-page h1 {
    margin: 0 0 12px;
    font-size: 2rem;
    line-height: 1.08;
    letter-spacing: -.025em;
}

@media (min-width: 768px) {
    .blog-page h1 {
        font-size: 2.15rem;
    }
}

@media (min-width: 1024px) {
    .blog-page h1 {
        font-size: 2.75rem;
    }
}

@media (min-width: 1280px) {
    .blog-page h1 {
        font-size: 3rem;
    }
}

/* The article */
.post-header {
    padding: 40px 0 28px;
    border-bottom: 1px solid var(--border);
    background: var(--light);
}

@media (min-width: 768px) {
    .post-header {
        padding: 64px 0 40px;
    }
}

.post-header h1 {
    max-width: 800px;
    margin: 16px 0;
    font-size: 2rem;
    line-height: 1.08;
    letter-spacing: -.025em;
}

@media (min-width: 768px) {
    .post-header h1 {
        font-size: 2.25rem;
    }
}

@media (min-width: 1024px) {
    .post-header h1 {
        font-size: 2.9rem;
    }
}

@media (min-width: 1280px) {
    .post-header h1 {
        font-size: 3.25rem;
    }
}

.post-header .lead {
    max-width: 720px;
}

.post-meta {
    margin: 0;
    color: var(--gray);
    font-size: .9rem;
}

.post-back {
    color: var(--accent-text);
    font-weight: 700;
}

.post-back:hover {
    text-decoration: underline;
}

.post-body {
    max-width: 720px;
    padding: 32px 0 16px;
}

@media (min-width: 768px) {
    .post-body {
        padding-top: 48px;
    }
}

.post-body p,
.post-body li {
    font-size: 1.05rem;
    line-height: 1.75;
    color: var(--dark);
}

@media (min-width: 768px) {
    .post-body p,
    .post-body li {
        font-size: 1.1rem;
    }
}

.post-body p {
    margin: 0 0 24px;
}

.post-body h2 {
    margin: 48px 0 16px;
    font-size: 1.75rem;
    line-height: 1.2;
    letter-spacing: -.02em;
}

.post-body h3 {
    margin: 32px 0 12px;
    font-size: 1.3rem;
}

.post-body ul {
    margin: 0 0 24px;
    padding-inline-start: 24px;
}

.post-body li {
    margin-bottom: 8px;
}

.post-body a {
    color: var(--accent-text);
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
}

.post-body blockquote {
    margin: 32px 0;
    padding: 20px 24px;
    border-inline-start: 4px solid var(--accent);
    border-radius: 0 12px 12px 0;
    background: var(--light);
}

.post-body blockquote p {
    margin: 0;
    font-size: 1.15rem;
    font-style: italic;
}

.post-body pre {
    margin: 0 0 24px;
    padding: 20px 24px;
    overflow-x: auto;
    border-radius: 12px;
    background: var(--ink);
    color: var(--on-ink);
    white-space: pre;
    word-break: normal;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .9rem;
    line-height: 1.6;
}

.post-body code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .95em;
}

.post-body p code,
.post-body li code {
    padding: 2px 6px;
    border-radius: 4px;
    background: rgba(var(--accent-rgb), .18);
}

.post-footer {
    max-width: 720px;
    padding: 24px 0 80px;
    border-top: 1px solid var(--border);
}

.post-footer .button {
    margin-top: 24px;
}

/* -----------------------------------------------------------------------------
   Contact: copy and the studio aside on the left, the form on the right
   -------------------------------------------------------------------------- */

/* Stacked up to 1024px, side by side from there */
.contact-row {
    display: block;
}

@media (min-width: 1024px) {
    .contact-row {
        display: flex;
        align-items: flex-start;
    }
}

.contact-copy {
    flex: 1 1 0;
    min-width: 0;
    margin-bottom: 32px;
}

@media (min-width: 1024px) {
    .contact-copy {
        margin-bottom: 0;
        padding-inline-end: 64px;
    }
}

.contact-email {
    margin: 0 0 32px;
    font-family: var(--headings-font);
    font-size: 1.25rem;
    font-weight: 700;
}

.contact-email a {
    color: var(--accent-text);
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 3px;
    text-underline-offset: 5px;
}

.contact-email a:hover {
    text-decoration-color: var(--accent-text);
}

.contact-aside {
    max-width: 480px;
    padding: 24px 20px;
    border-inline-start: 3px solid var(--accent);
    border-radius: 0 12px 12px 0;
    background: var(--light);
}

@media (min-width: 768px) {
    .contact-aside {
        padding: 24px;
    }
}

.contact-aside p {
    margin: 0 0 12px;
    color: var(--dark);
    line-height: 1.6;
}

.contact-form {
    position: relative;
    flex: 0 0 480px;
    max-width: 560px;
    padding: 24px 20px;
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    background: var(--light);
}

@media (min-width: 768px) {
    .contact-form {
        padding: 32px;
    }
}

@media (min-width: 1024px) {
    .contact-form {
        max-width: none;
    }
}

.contact-form label {
    margin-bottom: 6px;
    font-size: .85rem;
    font-weight: 600;
}

.contact-form textarea {
    min-height: 140px;
}

.contact-form .button {
    width: 100%;
    text-align: center;
}


/* After sending, the success message covers the form */
.contact-success {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 32px;
    border-radius: var(--radius-xl);
    background: var(--light);
    text-align: center;
}

.contact-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin-bottom: 16px;
    border-radius: 50%;
    background: rgba(var(--green-rgb), .12);
    color: var(--green);
    font-size: 1.75rem;
    font-weight: 700;
}

.contact-success strong {
    display: block;
    margin-bottom: 8px;
    font-family: var(--headings-font);
    font-size: 1.4rem;
}

.contact-success p {
    margin: 0 0 20px;
    color: var(--gray);
}

.contact-success .button {
    width: auto;
}

/* The status line of a form (setFormStatus() of ui.js), as in the
   app-boilerplate theme.css: right after its buttons, the error color for
   an error, the ink for success, gone while empty */
.form-status {
    margin: 12px 0 0 0;
    color: var(--gray);
    font-size: .95rem;
}

.form-status.is-error {
    color: var(--error-text);
}

.form-status.is-success {
    color: var(--black);
}

.form-status:empty {
    display: none;
}

/* -----------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer .footer-copyright {
    margin-top: 4px;
    font-size: .8rem;
}

/* -----------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .hero-copy > *,
    .portrait-frame,
    .portrait-frame::before,
    .hero-stars,
    .wave,
    .ticker-track {
        animation: none;
    }

    .job::before {
        transform: none;
        transition: none;
    }

    .card-grid > .custom-column > .inner-column > .wrapper:hover,
    .button:not([disabled]):hover {
        transform: none;
    }
}

