/* ==========================================================================
   Kennedy Software Solutions Inc.
   Single stylesheet. Loaded directly (there is no minified twin to keep in
   sync) — at this size the build step cost more than the bytes it saved.
   ========================================================================== */

/* --------------------------------------------------------------------------
   FONTS
   woff2 only: it covers ~98% of browsers, and every other format we used to
   ship (eot/ttf/svg/woff) targeted browsers that no longer exist.
   font-display belongs *here*, as a @font-face descriptor — not in a normal
   rule, where it is silently discarded and the face falls back to `auto`
   (up to 3s of invisible text).
   -------------------------------------------------------------------------- */
@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/roboto-v29-latin-regular.woff2') format('woff2');
}

/* Satisfy sets five decorative headings. `optional` lets the browser skip the
   swap entirely on a slow connection rather than reflowing them late. */
@font-face {
    font-family: 'Satisfy';
    font-style: normal;
    font-weight: 400;
    font-display: optional;
    src: url('../fonts/satisfy-v11-latin-regular.woff2') format('woff2');
}

/* --------------------------------------------------------------------------
   TOKENS
   Every value below is a rendered colour. The page used to carry
   `opacity: .8` on its container, which meant no colour was the colour the
   stylesheet claimed — and it pushed the skill chips to 4.09:1, under AA.
   Contrast against #FCFCFC is noted where it matters.
   -------------------------------------------------------------------------- */
:root {
    --kss-page:        #FCFCFC;
    --kss-ink:         #4F4F4F;  /*  7.98:1  body copy                  */
    --kss-ink-strong:  #333333;  /* 12.32:1  headings, captions         */
    --kss-link:        #2F4F8F;  /*  7.77:1  links                      */
    --kss-chip-bg:     #ECECEC;
    --kss-chip-ink:    #4F4F4F;  /*  6.93:1  on --kss-chip-bg           */
    --kss-field:       #FFFFFF;
    --kss-border:      #767676;  /*  4.43:1  control boundaries (1.4.11)*/
    --kss-button:      #E4E4E4;
    --kss-button-ink:  #2A2A2A;  /* 11.29:1  on --kss-button            */
    --kss-hairline:    #B0B0B0;  /* decorative rules only               */
    --kss-focus:       #1B4EC4;  /*  6.98:1  focus ring                 */
    --kss-caption-bg:  #FAFAFA;  /* opaque: caption contrast no longer
                                    depends on the photo behind it      */
}

/* --------------------------------------------------------------------------
   RESET
   Replaces the Meyer reset, which still named applet, acronym, big, center,
   strike, tt and hgroup — all removed from HTML — and applied box-sizing to
   two input types instead of everything.
   -------------------------------------------------------------------------- */
*, *::before, *::after {
    box-sizing: border-box;
}
body, h1, h2, h3, p, figure, figcaption, ul, ol, dl, dd, fieldset {
    margin: 0;
    padding: 0;
}
ul[class], ol[class] {
    list-style: none;
}
img, svg, picture {
    display: block;
    max-width: 100%;
}
img {
    height: auto;
}
input, textarea, button, select {
    font: inherit;
    color: inherit;
}
button {
    background: none;
    border: 0;
}

/* --------------------------------------------------------------------------
   BASE
   -------------------------------------------------------------------------- */
html {
    /* stops iOS Safari inflating text when the device is turned to landscape */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}
body {
    background-color: var(--kss-page);
    color: var(--kss-ink);
    font-family: 'Roboto', system-ui, sans-serif;
    line-height: 1.5;
}
a {
    color: var(--kss-link);
}

/* One focus style for the whole site. The old stylesheet defined none, and
   the container opacity dimmed the browser default on top of that. */
:focus-visible {
    outline: 3px solid var(--kss-focus);
    outline-offset: 2px;
    border-radius: 2px;
}

/* Names for icon-only links. Replaces `font-size: 0`, which left the link
   with no visible content at all once forced-colors mode dropped the CSS
   background images that were standing in for its label. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
    border: 0;
}

.kss-container {
    padding: 16px;
    margin: 0 auto;
    max-width: 1024px;
}

/* --------------------------------------------------------------------------
   HEADER
   -------------------------------------------------------------------------- */
.kss-header {
    padding-bottom: 16px;
}
/* The logo image *is* the page's h1; the heading itself carries no styling
   of its own. */
.kss-header h1 {
    font-size: inherit;
    font-weight: inherit;
}
.kss-header img {
    margin: 0 auto;
    opacity: .85;
}
.kss-description {
    padding: 16px 0;
    width: 90%;
    max-width: 62ch;
    text-align: center;
    margin: 0 auto;
}

/* --------------------------------------------------------------------------
   BANNERS
   figure/figcaption, so the caption is programmatically tied to its image.
   The photos are decorative (alt="") — the caption carries the message.
   -------------------------------------------------------------------------- */
.kss-banner {
    position: relative;
    padding: 24px 0;
}
.kss-banner img {
    width: 100%;
    opacity: .7;
}
.kss-banner figcaption {
    position: absolute;
    bottom: 34px;
    left: 8px;
    max-width: calc(100% - 16px);
    color: var(--kss-ink-strong);
    background-color: var(--kss-caption-bg);
    padding: 4px 6px;
}

/* Below ~420px the banner is short enough that an absolutely positioned
   caption can overflow past the top of its own image once it wraps. Put it
   back in flow rather than letting it escape. */
@media (max-width: 420px) {
    .kss-banner figcaption {
        position: static;
        margin-top: 8px;
        max-width: none;
    }
}

/* --------------------------------------------------------------------------
   SKILLS
   -------------------------------------------------------------------------- */
.kss-skills {
    text-align: center;
}

/* Centred heading flanked by rules. The old version faked this with
   line-height: .5, overflow: hidden and two 600px pseudo-elements, which
   clipped the descenders of the Satisfy face and cut off the second line
   entirely at 200% zoom. Flexbox does it without either hack. */
.kss-skills-title {
    display: flex;
    align-items: center;
    gap: 15px;
    font-family: 'Satisfy', cursive;
    font-weight: 400;
    font-size: 26px;
    line-height: 1.3;
    color: var(--kss-ink-strong);
    padding: 48px 16px 12px;
}
.kss-skills-title::before,
.kss-skills-title::after {
    content: "";
    flex: 1 1 auto;
    border-bottom: 1px solid var(--kss-hairline);
}

.kss-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 4px;
    padding: 32px 0;
}
.chip {
    background: var(--kss-chip-bg);
    color: var(--kss-chip-ink);
    padding: 8px 12px;
    border-radius: 32px;
    font-size: 16px;
}

/* --------------------------------------------------------------------------
   CONTACT FORM
   -------------------------------------------------------------------------- */
.kss-contact {
    padding: 48px 16px 16px;
}
.kss-contact-title {
    font-family: 'Satisfy', cursive;
    font-weight: 400;
    font-size: 26px;
    line-height: 1.3;
    color: var(--kss-ink-strong);
    text-align: center;
    padding-bottom: 12px;
}
.kss-contact form {
    max-width: 640px;
    margin: 0 auto;
}
.kss-field {
    margin-bottom: 20px;
}
.kss-field label {
    display: block;
    margin-bottom: 6px;
    color: var(--kss-ink-strong);
}
.kss-field input,
.kss-field textarea {
    display: block;
    width: 100%;
    padding: 8px 15px;
    background-color: var(--kss-field);
    border: 1px solid var(--kss-border);
    border-radius: 4px;
}
.kss-field textarea {
    resize: vertical;
}
.kss-submit {
    width: 100%;
    padding: 10px 15px;
    font-size: 16px;
    color: var(--kss-button-ink);
    background-color: var(--kss-button);
    border: 1px solid var(--kss-border);
    border-radius: 4px;
    cursor: pointer;
}
.kss-submit:hover {
    background-color: #D8D8D8;
}

/* Spam trap. Hidden from sight and from assistive technology, but a bot
   filling every field in the form will trip it. */
.kss-hp {
    position: absolute;
    left: -9999px;
}

/* --------------------------------------------------------------------------
   PROSE (privacy notice)
   -------------------------------------------------------------------------- */
.kss-prose {
    max-width: 70ch;
    margin: 0 auto;
    padding: 16px;
}
.kss-prose h1 {
    font-size: 32px;
    line-height: 1.25;
    color: var(--kss-ink-strong);
    padding: 12px 0;
}
.kss-prose h2 {
    font-size: 24px;
    line-height: 1.3;
    color: var(--kss-ink-strong);
    padding: 24px 0 8px;
}
.kss-prose p {
    padding: 6px 0;
}
.kss-prose ol,
.kss-prose ul {
    padding: 6px 0 6px 24px;
}
.kss-prose ol {
    list-style-type: decimal;
}
.kss-prose ul {
    list-style-type: circle;
}
.kss-prose li {
    padding: 3px 0;
}
.kss-prose hr {
    border: 0;
    border-top: 1px solid var(--kss-hairline);
    margin: 12px 0;
}
.kss-updated {
    color: var(--kss-ink);
    padding-bottom: 12px;
}

/* --------------------------------------------------------------------------
   FOOTER
   -------------------------------------------------------------------------- */
.kss-social {
    display: flex;
    justify-content: center;
    gap: 32px;
    padding: 48px 16px 16px;
}
.kss-social-icon {
    width: 64px;
    height: 64px;
}

/* The badges carry their own internal contrast (white glyph on a solid
   brand circle), so keep them rather than letting forced-colors flatten
   them into unrecognisable shapes. */
@media (forced-colors: active) {
    .kss-social-icon {
        forced-color-adjust: none;
    }
}

.notices {
    padding: 12px 0;
    text-align: center;
}
.notices a {
    /* inline-block so the margin actually applies — it is a dead
       declaration on an inline box */
    display: inline-block;
    margin-top: 12px;
}
.notices p {
    margin-top: 12px;
}

/* --------------------------------------------------------------------------
   MOTION
   Nothing here animates today; the guard keeps that true if anything is
   added later.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}
