/*
    Reusable Metal / Gunmetal Effect
    Inspired by Jhey Tompkins' CodePen metal button technique:
    - layered gradients
    - fixed-position reference light
    - border-box / padding-box background stacking
    - pseudo-element border bevel

    Usage:
      <button class="metal-effect metal-pill">Button</button>
      <div class="metal-effect metal-card">Content</div>
      <a class="metal-effect metal-button" href="#">Link</a>

    Optional:
      Add .metal-light-stage to a parent if you want the ambient colored light field visible
      behind the elements too.
*/

:root {
    color-scheme: light dark;

    /*
        These are the "environment lights".
        Because they use background-attachment: fixed on the actual metal element,
        the surface appears to catch different light depending on where it sits.
        That's the CodePen trick. Actual browser ray tracing remains rude and absent.
    */
    --metal-colors:
        radial-gradient(100% 100% at 50% 50%, hsl(140 90% 50% / 0.40), transparent 50%)
            50% 48% / 300px 108px no-repeat,
        radial-gradient(100% 100% at 50% 50%, hsl(10 90% 50% / 0.40), transparent 50%)
            calc(50% + 300px) 48% / 300px 108px no-repeat,
        radial-gradient(100% 100% at 50% 50%, hsl(210 90% 50% / 0.40), transparent 50%)
            calc(50% - 300px) 48% / 300px 108px no-repeat;

    --metal-reference:
        radial-gradient(100% 100% at 50% 50%, hsl(210 90% 70%) 25%, transparent 45%)
            calc(50% - 300px) 48% / 600px 110px border-box no-repeat,
        radial-gradient(100% 100% at 50% 50%, hsl(140 90% 70%) 25%, transparent 45%)
            50% 48% / 600px 110px border-box no-repeat,
        radial-gradient(100% 100% at 50% 50%, hsl(10 90% 70%) 25%, transparent 45%)
            calc(50% + 300px) 48% / 600px 110px border-box no-repeat;

    /*
        Default chrome-like metal shades.
        Override these per element or use the variants below.
    */
    --metal-shade-one: light-dark(hsl(0 0% 10%), hsl(0 0% 78%));
    --metal-shade-two: hsl(0 0% 70%);
    --metal-shade-three: hsl(0 0% 68%);
    --metal-shade-four: hsl(0 0% 98%);
    --metal-shade-five: hsl(0 0% 48%);
    --metal-shade-six: light-dark(hsl(0 0% 26%), hsl(0 0% 68%));
    --metal-shade-seven: hsl(0 0% 50%);

    --metal-radius: 999px;
    --metal-border-size: 3px;
    --metal-shadow: 0 0 1px 0 color-mix(in hsl, var(--metal-shade-four), transparent) inset,
                    0 10px 14px -10px hsl(0 0% 50%);
}

/*
    Optional visible ambient light layer.
    Use this on a wrapper/page section.
*/
.metal-light-stage {
    position: relative;
    isolation: isolate;
}

.metal-light-stage::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    filter: blur(20px);
    background: var(--metal-colors) fixed;
    background-attachment: fixed;
    opacity: var(--metal-stage-opacity, 1);
}

/*
    The reusable metal effect.
    Apply this class to almost anything:
    button, a, div, span, card, input suffix, etc.
*/
.metal-effect {
    --metal-border:
        linear-gradient(var(--metal-shade-one) 50%, var(--metal-shade-two)) border-box;

    --metal-base:
        linear-gradient(var(--metal-shade-three), var(--metal-shade-three)) padding-box;

    --metal-band:
        linear-gradient(
            var(--metal-shade-four) 5%,
            var(--metal-shade-five) 35%,
            var(--metal-shade-six) 50%,
            var(--metal-shade-five) 65%,
            var(--metal-shade-four) 95%
        ) border-box;

    --metal-radial:
        radial-gradient(
            160% 110% at 50% 100%,
            var(--metal-shade-seven),
            transparent 60%
        ) padding-box;

    position: relative;
    isolation: isolate;
    display: inline-grid;
    place-items: center;
    min-inline-size: 44px;
    min-block-size: 44px;
    padding: 0.65rem 1.15rem;
    border: var(--metal-border-size) solid transparent;
    border-radius: var(--metal-radius);
    color: var(--metal-text-color, light-dark(hsl(0 0% 10%), hsl(0 0% 96%)));
    font: inherit;
    font-weight: 700;
    text-decoration: none;
    text-align: center;
    line-height: 1;
    cursor: pointer;
    user-select: none;
    outline-color: var(--metal-outline-color, hsl(10 90% 50%));
    outline-offset: 4px;
    box-shadow: var(--metal-shadow);

    background:
        var(--metal-radial),
        var(--metal-base),
        var(--metal-reference),
        var(--metal-band);

    /*
        local layers stay glued to the element.
        fixed layers sample from the viewport/environment.
    */
    background-attachment:
        local,
        local,
        fixed,
        fixed;

    transition:
        transform 180ms ease,
        box-shadow 180ms ease,
        filter 180ms ease;
}

.metal-effect::after {
    content: "";
    position: absolute;
    inset: calc(var(--metal-border-size) * -1);
    z-index: 1;
    pointer-events: none;
    border: 1px solid transparent;
    border-radius: inherit;
    background: var(--metal-border);

    /*
        Creates a bevel ring from the background.
        Includes -webkit-mask for Chromium/Safari because naturally one syntax was not enough.
    */
    -webkit-mask:
        radial-gradient(#000, #000) padding-box,
        radial-gradient(#000, #000) border-box;
    -webkit-mask-composite: xor;

    mask:
        radial-gradient(#000, #000) padding-box,
        radial-gradient(#000, #000) border-box;
    mask-composite: subtract;
}

button .metal-effect:hover {
    filter: brightness(1.04) contrast(1.03);
    transform: translateY(-1px);
    box-shadow:
        0 0 1px 0 color-mix(in hsl, var(--metal-shade-four), transparent) inset,
        0 14px 22px -14px hsl(0 0% 35%);
}

button .metal-effect:active {
    transform: translateY(1px);
    filter: brightness(0.96) contrast(1.02);
    box-shadow:
        0 0 1px 0 color-mix(in hsl, var(--metal-shade-four), transparent) inset,
        0 7px 10px -10px hsl(0 0% 35%);
}

/*
    Useful shapes.
*/
.metal-pill {
    inline-size: 300px;
    block-size: calc(44px + 1rem);
}

.metal-icon {
    inline-size: 44px;
    block-size: 44px;
    padding: 0;
}

.metal-square {
    inline-size: 72px;
    block-size: 72px;
    padding: 0;
    --metal-radius: 18px;
}

.metal-card {
    display: block;
    --metal-radius: 28px;
    min-block-size: 160px;
    padding: 1.5rem;
    line-height: 1.5;
    cursor: default;
}

.metal-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    --metal-radius: 24px;
    min-block-size: 72px;
    padding: 1rem 1.25rem;
    cursor: default;
}

.metal-effect svg {
    inline-size: 1.2em;
    block-size: 1.2em;
    color: hsl(0 0% 94%);
    transform: translateY(6%);
    position: relative;
}

.metal-effect svg path,
.metal-effect svg :is(path, circle, rect, line, polyline, polygon) {
    transform-box: fill-box;
    transform-origin: 50% 0;
    filter: drop-shadow(0 -1px 0 hsl(0 0% 48%));
}

/*
    Gunmetal variant.
    Darker, colder, less shiny than the original chrome.
*/
.metal-gunmetal {
    --metal-shade-one: light-dark(hsl(210 12% 7%), hsl(210 10% 58%));
    --metal-shade-two: hsl(213 11% 36%);
    --metal-shade-three: hsl(213 13% 26%);
    --metal-shade-four: hsl(210 17% 74%);
    --metal-shade-five: hsl(214 13% 24%);
    --metal-shade-six: light-dark(hsl(215 18% 13%), hsl(212 10% 42%));
    --metal-shade-seven: hsl(210 13% 28%);
    --metal-text-color: hsl(210 20% 94%);
    --metal-shadow:
        inset 0 1px 1px hsl(210 35% 90% / 0.18),
        inset 0 -2px 6px hsl(210 30% 2% / 0.75),
        0 16px 24px -16px hsl(210 30% 2% / 0.95);
}

/*
    Blackened steel variant.
*/
.metal-black {
    --metal-shade-one: light-dark(hsl(220 10% 5%), hsl(220 8% 48%));
    --metal-shade-two: hsl(220 7% 24%);
    --metal-shade-three: hsl(220 8% 16%);
    --metal-shade-four: hsl(220 12% 58%);
    --metal-shade-five: hsl(220 8% 17%);
    --metal-shade-six: hsl(220 9% 8%);
    --metal-shade-seven: hsl(220 7% 18%);
    --metal-text-color: hsl(0 0% 96%);
}

/*
    Brushed line overlay. Optional, but it helps panels/cards.
*/
.metal-brushed::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    border-radius: inherit;
    background:
        repeating-linear-gradient(
            0deg,
            hsl(0 0% 100% / 0.055) 0,
            hsl(0 0% 100% / 0.018) 1px,
            hsl(0 0% 0% / 0.06) 2px,
            hsl(0 0% 0% / 0.02) 4px
        );
    mix-blend-mode: overlay;
    opacity: 0.55;
}

.metal-effect > * {
    position: relative;
    z-index: 2;
}

/*
    Input pattern.
*/
.metal-input-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.metal-input-wrap > input {
    inline-size: 300px;
    block-size: calc(44px + 1rem);
    padding-inline: 1rem 4rem;
    border: 0;
    border-radius: 999px;
    outline-color: hsl(10 90% 50%);
    background: light-dark(white, black);
    color: canvasText;
    font: inherit;
}

.metal-input-wrap > .metal-effect {
    position: absolute;
    inset-inline-end: 0.5rem;
    inset-block-start: 50%;
    translate: 0 -50%;

    /*
        The original CodePen removes the fixed color reference on the inner input button.
        Keeping that behavior here makes the small icon button cleaner.
    */
    --metal-reference: linear-gradient(transparent, transparent);
}

/*
    Demo-only helpers.
    You can delete these in your app.
*/
.metal-demo-page {
    min-block-size: 100vh;
    margin: 0;
    display: grid;
    place-items: center;
    overflow-x: hidden;
    font-family:
        "SF Pro Text",
        "SF Pro Icons",
        "Helvetica Neue",
        Helvetica,
        Arial,
        sans-serif,
        system-ui;
    background: color-mix(in hsl, canvas, canvasText 6%);
}

.metal-demo-page::before {
    --size: 45px;
    --line: color-mix(in lch, canvasText, transparent 70%);

    content: "";
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background:
        linear-gradient(90deg, var(--line) 1px, transparent 1px var(--size)) 50% 50% / var(--size) var(--size),
        linear-gradient(var(--line) 1px, transparent 1px var(--size)) 50% 50% / var(--size) var(--size);
    mask: linear-gradient(-20deg, transparent 50%, white);
}

.metal-demo-main {
    width: min(980px, calc(100vw - 2rem));
    display: grid;
    gap: 2.5rem;
    place-items: center;
    padding: 4rem 1rem;
}

.metal-demo-grid {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
}

.metal-demo-copy {
    max-width: 760px;
    text-align: center;
    color: color-mix(in hsl, canvasText, transparent 22%);
    line-height: 1.6;
}

@media (max-width: 760px) {
    .metal-demo-grid {
        grid-template-columns: 1fr;
    }

    .metal-pill,
    .metal-input-wrap > input {
        inline-size: min(300px, calc(100vw - 3rem));
    }
}

/*
    Fallback if CSS light-dark is unsupported.
*/
@supports not (color: light-dark(white, black)) {
    :root {
        --metal-shade-one: hsl(0 0% 10%);
        --metal-shade-six: hsl(0 0% 26%);
    }

    .metal-input-wrap > input {
        background: white;
        color: black;
    }
}
