@font-face {
    font-family: 'EB Garamond';
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url('/storage/production/styles/thornwood/font-eb-garamond-400-italic-fc5851c4.woff2') format('woff2');
}

@font-face {
    font-family: 'EB Garamond';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/storage/production/styles/thornwood/font-eb-garamond-400-normal-912929db.woff2') format('woff2');
}

@font-face {
    font-family: 'EB Garamond';
    font-style: italic;
    font-weight: 500;
    font-display: swap;
    src: url('/storage/production/styles/thornwood/font-eb-garamond-500-italic-b2698d7d.woff2') format('woff2');
}

@font-face {
    font-family: 'EB Garamond';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/storage/production/styles/thornwood/font-eb-garamond-500-normal-7b252686.woff2') format('woff2');
}

@font-face {
    font-family: 'EB Garamond';
    font-style: italic;
    font-weight: 600;
    font-display: swap;
    src: url('/storage/production/styles/thornwood/font-eb-garamond-600-italic-a787b3a1.woff2') format('woff2');
}

@font-face {
    font-family: 'EB Garamond';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/storage/production/styles/thornwood/font-eb-garamond-600-normal-6a195b7e.woff2') format('woff2');
}

@font-face {
    font-family: 'IM Fell English';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/storage/production/styles/thornwood/font-im-fell-english-400-normal-248300df.woff2') format('woff2');
}

@media (prefers-reduced-motion: no-preference) {
    @keyframes thornwood-token-placed {
        from {
            opacity: 0;
            scale: 1.35;
            translate: 0.15rem -0.35rem;
            rotate: calc(var(--editor-tilt, 0deg) * 2.5);
        }
    }
    /* No fade and no scale: the same token, elsewhere a moment ago. */
    @keyframes thornwood-token-slid {
        from {
            translate: var(--editor-from-x, 0) var(--editor-from-y, 0);
            rotate: var(--editor-from-tilt, var(--editor-tilt, 0deg));
        }
    }
}

@layer styles {
    [data-sheet-style='thornwood'] {
        /* A line on the bark: moss, so a row has an outline that can be seen. */
        --edge: rgb(64 94 64);

        /* A row or a tray lying on the forest floor: bark with nothing growing through it, so what is written there has something plain behind it. */
        --panel: rgb(14 28 16);

        /* Old vellum. Every card, the table the cards lie on, and a place card. */
        --paper: rgb(223 215 197);

        /* A filled button on the forest floor. */
        --action: rgb(35 71 37);

        /* Menus that open over the page. */
        --chrome: rgb(12 23 13);
        --tone-1: rgb(129 81 33);
        --tone-2: rgb(43 86 121);
        --tone-3: rgb(102 65 118);
        --tone-4: rgb(37 96 65);

        /* Bark, moss, lichen, and the little bit of light that gets through. */
        --surface: rgb(5 12 6);

        /* The table, and a token laid on a card. */
        --tw-bark: rgb(14 22 14);

        /* Something still living in it. */
        --tw-glow: rgb(101 149 90);

        /* The menu, a shade under the bark. */
        --tw-menu: rgb(9 18 10);

        /* Every line drawn on the bark, at one strength or another. */
        --tw-moss: rgb(51 87 53);

        /* A burnt tag, still smouldering. */
        --tw-ember: rgb(236 125 0);

        /* The light along a top edge. */
        --tw-sheen: rgb(255 255 255);

        /* A weakness: the bar down its edge, then its wash and its ink. */
        --tw-thorn: rgb(140 52 50);

        /* How a well-handled card darkens towards its edges, and ink where a nib is resting. */
        --tw-umber: rgb(153 130 101);
        --card-trim: var(--rank-1-trim);
        --font-body: 'EB Garamond', ui-serif, Georgia, serif;

        /* The second line of anything written on the bark. Light enough to read against the moss. */
        --ink-muted: rgb(177 188 161);
        --paper-ink: rgb(47 36 28);

        /* The rules printed inside a card. */
        --tw-bronze: rgb(141 106 67);

        /* What is written on the bark. */
        --tw-lichen: rgb(169 193 146);

        /* Every shadow, which is green-black rather than black. */
        --tw-shadow: rgb(0 2 1);

        /* The cloth a reading is laid on: dark wine, towards purple, so a panel is not one more green thing on the forest floor. */
        --tw-velvet: rgb(32 10 30);
        --action-ink: rgb(226 232 210);
        --chrome-ink: var(--tw-lichen);
        --paper-edge: rgb(164 150 128);
        --tone-1-ink: var(--tone-1);
        --tone-2-ink: var(--tone-2);
        --tone-3-ink: var(--tone-3);
        --tone-4-ink: var(--tone-4);
        --tone-plain: rgb(82 76 71);
        --card-corner: var(--tw-corner-plain);

        /* Might unchosen: the plainest the style gets — small, and barely coloured. */
        --rank-0-trim: rgb(95 79 67);

        /* Origin: bronze, unpolished. The card this style was drawn against. */
        --rank-1-trim: rgb(134 91 61);

        /* Adventure: bronze that has been polished. */
        --rank-2-trim: rgb(176 110 62);

        /* Greatness: the same shine, gone to amethyst. */
        --rank-3-trim: rgb(125 60 181);
        --tone-1-edge: rgb(121 93 60);
        --tone-1-wash: var(--paper);
        --tone-2-edge: rgb(67 98 119);
        --tone-2-wash: var(--paper);
        --tone-3-edge: rgb(107 83 117);
        --tone-3-wash: var(--paper);
        --tone-4-edge: rgb(61 98 76);
        --tone-4-wash: var(--paper);

        /* Bark with a little light on it: a status card, a chair somebody is in. */
        --tw-bark-lit: rgb(17 30 19);
        --font-display: 'IM Fell English', 'EB Garamond', ui-serif, serif;
        --rank-2-shine: linear-gradient(118deg, transparent 20%, rgb(242 200 156 / 0.8) 38%, transparent 54%);
        --rank-3-shine: linear-gradient(118deg, transparent 18%, rgb(220 174 254 / 0.9) 36%, transparent 52%);

        /* Moss in shadow: a wash behind something, and a button pressed into paper. */
        --tw-moss-deep: rgb(28 50 26);
        --tw-thorn-ink: rgb(107 30 29);

        /* The cloth a reading is laid on: light catching across the pile, over the velvet itself. The velvet is grey — it takes its colour from `tw-velvet` — so the cloth is re-dyed by changing that one colour. Top layer first; the CSS blends two layers in this order. */
        --panel-texture: linear-gradient(100deg, transparent 20%, rgb(169 193 146 / 0.07) 48%, transparent 75%),
url('/storage/production/styles/thornwood/velvet-ad432517.svg');

        /* The tooth of the paper. */
        --paper-texture: url('/storage/production/styles/thornwood/parchment-c39e5cce.png');
        --rank-2-corner: var(--tw-corner-rich);
        --rank-3-corner: var(--tw-corner-crown);

        /* The same, held back: a page title, a tab not chosen. */
        --tw-lichen-dim: rgb(116 135 105);

        /* The reverse of a card. */
        --tw-paper-back: rgb(217 208 189);
        --tw-thorn-wash: rgb(205 148 143 / 0.3);

        /* The same cloth where the pile is brushed up: the one that is open, in a list on the velvet. */
        --tw-velvet-lit: rgb(80 37 75);
        --tone-plain-ink: var(--tone-plain);
        --tw-bronze-deep: rgb(105 67 35);
        --tw-corner-rich: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='46' height='46' fill='none' stroke='%23000' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M1.5 45V9.5Q1.5 1.5 9.5 1.5H45'/%3E%3Cpath d='M5.5 27Q5.5 5.5 27 5.5' stroke-opacity='.55'/%3E%3Cpath d='M9 34Q9 9 34 9' stroke-opacity='.28'/%3E%3Cpath d='M15 7.5Q7.5 7.5 7.5 15' stroke-opacity='.85'/%3E%3Cpath d='M11 21Q15 16.5 21 15.5' stroke-opacity='.55'/%3E%3Cpath d='M21 11Q16.5 15 15.5 21' stroke-opacity='.55'/%3E%3Cpath d='M22 3.5V7.5' stroke-opacity='.5'/%3E%3Cpath d='M31 3.5V6.5' stroke-opacity='.38'/%3E%3Cpath d='M3.5 22H7.5' stroke-opacity='.5'/%3E%3Cpath d='M3.5 31H6.5' stroke-opacity='.38'/%3E%3Ccircle cx='16.5' cy='16.5' r='2.2' fill='%23000' stroke='none' fill-opacity='.7'/%3E%3Ccircle cx='38' cy='4.5' r='1.3' fill='%23000' stroke='none' fill-opacity='.5'/%3E%3Ccircle cx='4.5' cy='38' r='1.3' fill='%23000' stroke='none' fill-opacity='.5'/%3E%3C/svg%3E");
        --paper-ink-muted: rgb(95 83 70);

        /* The forest floor: a fleck of moss over everything, two lights coming down through leaves, and the dark gathering at the bottom. Top layer first. The blend modes in the CSS expect four layers in this order. */
        --surface-texture: url('/storage/production/styles/thornwood/moss-03514974.png'),
radial-gradient(70% 45% at 22% 8%, rgb(47 82 39 / 0.4), transparent 72%),
radial-gradient(55% 40% at 88% 26%, rgb(22 65 45 / 0.34), transparent 70%),
radial-gradient(90% 55% at 50% 108%, rgb(1 5 2 / 0.95), transparent 70%);
        --tone-plain-edge: rgb(120 102 72);
        --tone-plain-wash: var(--paper);

        /* The highlight on polished bronze. */
        --tw-bronze-light: rgb(242 200 156);
        --tw-corner-crown: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='50' height='50' fill='none' stroke='%23000' stroke-width='1.25' stroke-linecap='round'%3E%3Cpath d='M1.5 49V10Q1.5 1.5 10 1.5H49'/%3E%3Cpath d='M5.5 28Q5.5 5.5 28 5.5' stroke-opacity='.55'/%3E%3Cpath d='M16 8Q8 8 8 16' stroke-opacity='.85'/%3E%3Cpath d='M11 24Q16 18 24 16' stroke-opacity='.6'/%3E%3Cpath d='M24 11Q18 16 16 24' stroke-opacity='.6'/%3E%3Cpath d='M13 33Q20 26 30 22' stroke-opacity='.35'/%3E%3Cpath d='M33 13Q26 20 22 30' stroke-opacity='.35'/%3E%3Ccircle cx='18' cy='18' r='2.4' fill='%23000' stroke='none' fill-opacity='.7'/%3E%3Ccircle cx='34' cy='4.5' r='1.4' fill='%23000' stroke='none' fill-opacity='.55'/%3E%3Ccircle cx='4.5' cy='34' r='1.4' fill='%23000' stroke='none' fill-opacity='.55'/%3E%3Ccircle cx='43' cy='4.5' r='1' fill='%23000' stroke='none' fill-opacity='.4'/%3E%3Ccircle cx='4.5' cy='43' r='1' fill='%23000' stroke='none' fill-opacity='.4'/%3E%3C/svg%3E");

        /* The corner brackets, as masks rather than pictures. Drawn in black at whatever opacity each stroke wants, then used for their alpha alone — which is what lets the gild be a colour a card can change. Three of them, getting more elaborate, because a mightier theme is meant to be a more decorated card. */
        --tw-corner-plain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34' height='34' fill='none' stroke='%23000' stroke-width='1.15' stroke-linecap='round'%3E%3Cpath d='M1.5 33V8Q1.5 1.5 8 1.5H33'/%3E%3Cpath d='M6.5 19Q6.5 6.5 19 6.5' stroke-opacity='.45'/%3E%3Cpath d='M12 6.8Q6.8 6.8 6.8 12' stroke-opacity='.75'/%3E%3Ccircle cx='13.5' cy='13.5' r='1.5' fill='%23000' stroke='none' fill-opacity='.6'/%3E%3C/svg%3E");

        /* Paper where it is cleanest: a field, lettering on a pressed button. */
        --tw-vellum-light: rgb(237 231 219);
        --tw-vellum-shade: rgb(196 185 165);
        --card-corner-size: 34px;
        --card-corner-tint: tint;

        /* The light inside amethyst. */
        --tw-amethyst-light: rgb(220 174 254);
        --rank-0-corner-size: 30px;
        --rank-1-corner-size: 34px;
        --rank-2-corner-size: 46px;
        --rank-3-corner-size: 50px;
    }

    [data-sheet-style='thornwood'] [data-form='card'] {
        --trim: var(--card-trim);
        --shine: none;
    }
    [data-sheet-style='thornwood'] [data-form='card']::before,
    [data-sheet-style='thornwood'] [data-form='card'] [data-slot='card-frame']::before {
        content: '';
        position: absolute;
        z-index: 1;
        width: var(--card-corner-size);
        height: var(--card-corner-size);
        pointer-events: none;
        background-color: var(--trim, currentColor);
        background-image: var(--shine, none);
        -webkit-mask: var(--card-corner) center / 100% 100% no-repeat;
        mask: var(--card-corner) center / 100% 100% no-repeat;
    }
    [data-sheet-style='thornwood'] [data-form='card']::before {
        top: 4px;
        left: 4px;
    }
    [data-sheet-style='thornwood'] [data-form='card'] [data-slot='card-frame']::before {
        top: -1px;
        right: -1px;
        transform: scaleX(-1);
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='0'] {
        --trim: var(--rank-0-trim);
        --shine: none;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='0']::before,
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='0'] [data-slot='card-frame']::before {
        content: '';
        position: absolute;
        z-index: 1;
        width: var(--rank-0-corner-size);
        height: var(--rank-0-corner-size);
        pointer-events: none;
        background-color: var(--trim, currentColor);
        background-image: var(--shine, none);
        -webkit-mask: var(--card-corner) center / 100% 100% no-repeat;
        mask: var(--card-corner) center / 100% 100% no-repeat;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='0']::before {
        top: 4px;
        left: 4px;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='0'] [data-slot='card-frame']::before {
        top: -1px;
        right: -1px;
        transform: scaleX(-1);
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='1'] {
        --trim: var(--rank-1-trim);
        --shine: none;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='1']::before,
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='1'] [data-slot='card-frame']::before {
        content: '';
        position: absolute;
        z-index: 1;
        width: var(--rank-1-corner-size);
        height: var(--rank-1-corner-size);
        pointer-events: none;
        background-color: var(--trim, currentColor);
        background-image: var(--shine, none);
        -webkit-mask: var(--card-corner) center / 100% 100% no-repeat;
        mask: var(--card-corner) center / 100% 100% no-repeat;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='1']::before {
        top: 4px;
        left: 4px;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='1'] [data-slot='card-frame']::before {
        top: -1px;
        right: -1px;
        transform: scaleX(-1);
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='2'] {
        --trim: var(--rank-2-trim);
        --shine: var(--rank-2-shine);
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='2']::before,
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='2'] [data-slot='card-frame']::before {
        content: '';
        position: absolute;
        z-index: 1;
        width: var(--rank-2-corner-size);
        height: var(--rank-2-corner-size);
        pointer-events: none;
        background-color: var(--trim, currentColor);
        background-image: var(--shine, none);
        -webkit-mask: var(--rank-2-corner) center / 100% 100% no-repeat;
        mask: var(--rank-2-corner) center / 100% 100% no-repeat;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='2']::before {
        top: 4px;
        left: 4px;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='2'] [data-slot='card-frame']::before {
        top: -1px;
        right: -1px;
        transform: scaleX(-1);
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='3'] {
        --trim: var(--rank-3-trim);
        --shine: var(--rank-3-shine);
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='3']::before,
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='3'] [data-slot='card-frame']::before {
        content: '';
        position: absolute;
        z-index: 1;
        width: var(--rank-3-corner-size);
        height: var(--rank-3-corner-size);
        pointer-events: none;
        background-color: var(--trim, currentColor);
        background-image: var(--shine, none);
        -webkit-mask: var(--rank-3-corner) center / 100% 100% no-repeat;
        mask: var(--rank-3-corner) center / 100% 100% no-repeat;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='3']::before {
        top: 4px;
        left: 4px;
    }
    [data-sheet-style='thornwood'] [data-form='card'][data-card-rank='3'] [data-slot='card-frame']::before {
        top: -1px;
        right: -1px;
        transform: scaleX(-1);
    }

    /*
     * Thornwood — a mossy, forested style, and the first real test of whether the style
     * architecture earns its keep.
     *
     * Everything here hangs off `data-sheet-style="thornwood"` on the root element and the
     * `data-slot` hooks the components expose. No component knows this file exists, and
     * nothing here leaks into another style.
     */
    [data-sheet-style='thornwood'] {
        font-family: var(--font-body);
    }

    /* ---------------------------------------------------------------- the forest floor */
    [data-sheet-style='thornwood'] [data-slot='surface'] {
        background-color: var(--surface);
        /* The layers are a knob — `surface-texture`. Moss, then three lights. */
        background-image: var(--surface-texture);
        background-blend-mode: soft-light, screen, screen, normal;
    }

    /* --------------------------------------------------------------------------- cards */
    [data-sheet-style='thornwood'] [data-form='card'] {
        /*
         * Tarot faces are light, on a dark table. The ink and the rules on a card already
         * follow its paper; these are the rest of what is drawn on one.
         */
        --color-background: var(--tw-vellum-light);
        --color-primary: var(--tw-moss-deep);
        --color-primary-foreground: var(--tw-vellum-light);
        --color-accent: rgb(153 130 101 / 0.18);
        --color-accent-foreground: var(--paper-ink);
        /* Avatar and other muted fills, or an empty portrait is a hole in the paper. */
        --color-muted: var(--tw-vellum-shade);

        /*
         * A weakness reads as something caught under the style rather than a red highlight.
         * On a card only: this is a thin wash and a dark ink, both mixed for parchment, and
         * off the card there is no parchment for them to sit on.
         */
        --hinders-wash: var(--tw-thorn-wash);
        --hinders-edge: rgb(140 52 50 / 0.5);
        --hinders-ink: var(--tw-thorn-ink);

        color: var(--paper-ink);

        /*
         * A printed mat. Content is full-bleed by default, so without this the edge of a
         * card in the pile shows a slice of whatever band happens to be there. Five pixels
         * of clean paper is what a real card shows you.
         */
        padding: 5px;

        /* Squarer than the default: old vellum, cut by hand. */
        border-radius: 0.5rem;
        background-color: var(--paper);
        background-image:
            /* the tooth of the paper */
            var(--paper-texture),
            /* and the way a well-handled card darkens towards its edges */
            radial-gradient(
                    125% 90% at 50% 42%,
                    transparent 48%,
                    rgb(153 130 101 / 0.32) 100%
                ); background-image:
            /* the tooth of the paper */
            var(--paper-texture),
            /* and the way a well-handled card darkens towards its edges */
            radial-gradient(
                    125% 90% at 50% 42%,
                    transparent 48%,
                    oklch(from var(--tw-umber) l c h / 0.32) 100%
                );
        /*
         * A card is the thing that moves, so its shadow is rasterised again every frame of
         * a drag, and that cost grows with the blur radius. 26px of blur measured at 28% of
         * the style's raster time on its own; 11px reads the same at arm's length on a phone
         * once the alpha is brought up to compensate. See the note on textures below.
         */
        box-shadow:
            0 1px 0 rgb(255 255 255 / 0.35) inset,
            0 4px 11px rgb(0 2 1 / 0.8); box-shadow:
            0 1px 0 oklch(from var(--tw-sheen) l c h / 0.35) inset,
            0 4px 11px oklch(from var(--tw-shadow) l c h / 0.8);
    }

    /*
     * The reverse of a card carries the deck's lattice, so a card turned over in the pile
     * shows the same back you see at the edges. Kept faint behind the text.
     */
    [data-sheet-style='thornwood'] [data-card-face='back'] {
        border-color: var(--tw-bronze);
        background-color: var(--tw-paper-back);
        background-image:
            url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Cg fill='none' stroke='%237a5c2a' stroke-opacity='.09' stroke-width='.85'%3E%3Cpath d='M11 1.5 20.5 11 11 20.5 1.5 11Z'/%3E%3Ccircle cx='11' cy='11' r='2'/%3E%3C/g%3E%3C/svg%3E"),
            radial-gradient(
                125% 90% at 50% 42%,
                transparent 45%,
                rgb(153 130 101 / 0.36) 100%
            ); background-image:
            url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Cg fill='none' stroke='%237a5c2a' stroke-opacity='.09' stroke-width='.85'%3E%3Cpath d='M11 1.5 20.5 11 11 20.5 1.5 11Z'/%3E%3Ccircle cx='11' cy='11' r='2'/%3E%3C/g%3E%3C/svg%3E"),
            radial-gradient(
                125% 90% at 50% 42%,
                transparent 45%,
                oklch(from var(--tw-umber) l c h / 0.36) 100%
            );
        box-shadow:
            0 0 0 1px rgb(141 106 67 / 0.6) inset,
            0 0 0 5px var(--tw-paper-back) inset,
            0 0 0 6px rgb(141 106 67 / 0.4) inset,
            0 4px 11px rgb(0 2 1 / 0.8); box-shadow:
            0 0 0 1px oklch(from var(--tw-bronze) l c h / 0.6) inset,
            0 0 0 5px var(--tw-paper-back) inset,
            0 0 0 6px oklch(from var(--tw-bronze) l c h / 0.4) inset,
            0 4px 11px oklch(from var(--tw-shadow) l c h / 0.8);
    }

    /* ----------------------------------------------------------------------- might */
    /*
     * A mightier theme is a richer card. What its corners are, what they are made of and how
     * large they are drawn is set per rank in the style's decorations; what is left here is
     * each rank's edge, and the extra rules inside its frame.
     */
    /*
     * Adventure: bronze that has been polished. Warmer and darker than gold — a yellow this
     * bright on parchment stops reading as metal and starts reading as highlighter — and the
     * highlight is warm too rather than white, which is what keeps it looking struck.
     *
     * The arms carry more here than they did when there were four of them: three nested
     * sweeps, ticks down both edges, and a boss where they meet.
     */
    [data-sheet-style='thornwood'] [data-card-rank='2'] {
        border-color: var(--rank-1-trim);
    }

    [data-sheet-style='thornwood'] [data-card-rank='2'] [data-slot='card-frame'] {
        box-shadow:
            0 0 0 1px rgb(176 110 62 / 0.6) inset,
            0 0 0 3px rgb(176 110 62 / 0.18) inset,
            0 0 0 4px rgb(176 110 62 / 0.32) inset; box-shadow:
            0 0 0 1px oklch(from var(--rank-2-trim) l c h / 0.6) inset,
            0 0 0 3px oklch(from var(--rank-2-trim) l c h / 0.18) inset,
            0 0 0 4px oklch(from var(--rank-2-trim) l c h / 0.32) inset;
    }

    /*
     * Greatness: the same shine, gone to amethyst.
     *
     * Purple rather than red, and not only for taste: a weakness tag is drawn as a red band,
     * and a red card would be saying that word twice about two unrelated things. It also
     * agrees with the suit colour Greatness already carries.
     */
    [data-sheet-style='thornwood'] [data-card-rank='3'] {
        border-color: var(--rank-3-trim);

        /*
         * The glow is kept to 10px. Blur radius is the expensive part of a shadow on a card
         * that moves, and this one is additional to the shadow every card already casts —
         * affordable because a character has one or two Greatness themes, not eight.
         */
        box-shadow:
            0 1px 0 rgb(255 255 255 / 0.35) inset,
            0 0 10px rgb(125 60 181 / 0.38),
            0 4px 11px rgb(0 2 1 / 0.8); box-shadow:
            0 1px 0 oklch(from var(--tw-sheen) l c h / 0.35) inset,
            0 0 10px oklch(from var(--rank-3-trim) l c h / 0.38),
            0 4px 11px oklch(from var(--tw-shadow) l c h / 0.8);
    }

    [data-sheet-style='thornwood'] [data-card-rank='3'] [data-slot='card-frame'] {
        box-shadow:
            0 0 0 1px rgb(125 60 181 / 0.65) inset,
            0 0 0 2px rgb(125 60 181 / 0.2) inset,
            0 0 0 4px rgb(125 60 181 / 0.35) inset,
            0 0 0 5px rgb(125 60 181 / 0.14) inset; box-shadow:
            0 0 0 1px oklch(from var(--rank-3-trim) l c h / 0.65) inset,
            0 0 0 2px oklch(from var(--rank-3-trim) l c h / 0.2) inset,
            0 0 0 4px oklch(from var(--rank-3-trim) l c h / 0.35) inset,
            0 0 0 5px oklch(from var(--rank-3-trim) l c h / 0.14) inset;
    }

    /*
     * The kind printed along the top edge is gilded to match, and outlined so it stays put.
     *
     * The glow alone lit the letters from every side at once and they came apart — small caps
     * at this size have almost no stem to lose. The stroke is drawn under the fill rather than
     * over it, so it grounds the shape without eating into it.
     */
    [data-sheet-style='thornwood'] [data-card-rank='2'] [data-slot='card-kind-label'],
    [data-sheet-style='thornwood'] [data-card-rank='3'] [data-slot='card-kind-label'] {
        color: var(--trim);
        paint-order: stroke fill;
        -webkit-text-stroke: 0.7px color-mix(in oklab, var(--trim) 30%, black);
        text-shadow: 0 0 5px color-mix(in oklab, var(--trim) 35%, transparent);
    }

    /*
     * The picker takes the same top edge while a card is open, and takes none of that: it is
     * a control, and has to be read rather than admired.
     */
    [data-sheet-style='thornwood'] [data-slot='might-picker'] {
        color: var(--tw-bronze-deep);
        paint-order: normal;
        -webkit-text-stroke: 0;
        text-shadow: none;
    }

    [data-sheet-style='thornwood'] [data-slot='card-frame'] {
        border-radius: 0.35rem;
        /* An inner rule, set in from the cut edge like a printed frame. */
        box-shadow:
            0 0 0 1px rgb(141 106 67 / 0.45) inset,
            0 0 0 3px rgb(141 106 67 / 0.12) inset; box-shadow:
            0 0 0 1px oklch(from var(--tw-bronze) l c h / 0.45) inset,
            0 0 0 3px oklch(from var(--tw-bronze) l c h / 0.12) inset;
        margin: 5px;
    }

    /* --------------------------------------------------------------- open for changes */
    /*
     * A card being written on wants less of all this. The ornament is for the card in play —
     * while somebody is filling fields in, it is between them and the work, and the corner
     * brackets are large enough at the higher mights to crowd the top of a phone-width card.
     *
     * Toned rather than removed, so the card does not change character when the pencil is
     * pressed: the same card, with the lamp turned down.
     */
    [data-sheet-style='thornwood'] [data-form='card'][data-editing]::before,
    [data-sheet-style='thornwood'] [data-editing] [data-slot='card-frame']::before {
        opacity: 0.35;
    }

    [data-sheet-style='thornwood'] [data-card-rank='2'][data-editing],
    [data-sheet-style='thornwood'] [data-card-rank='3'][data-editing] {
        --shine: none;
    }

    /* And the glow goes out entirely — it is the one part that reads as a lit surface. */
    [data-sheet-style='thornwood'] [data-card-rank='3'][data-editing] {
        box-shadow:
            0 1px 0 rgb(255 255 255 / 0.35) inset,
            0 4px 11px rgb(0 2 1 / 0.8); box-shadow:
            0 1px 0 oklch(from var(--tw-sheen) l c h / 0.35) inset,
            0 4px 11px oklch(from var(--tw-shadow) l c h / 0.8);
    }

    [data-sheet-style='thornwood'] [data-editing] [data-slot='card-kind-label'] {
        text-shadow: none;
    }

    /* ------------------------------------------------------------- rules and tracks */
    /*
     * Everything ruled on the card is drawn in the same metal as its corners, so a card reads
     * as one object rather than as a bordered thing with grey furniture inside it. All of it
     * hangs off `--trim`, which means the whole card follows the might without a single
     * rule here naming one.
     */
    [data-sheet-style='thornwood'] [data-slot='card-rule'] {
        background-color: color-mix(in oklab, var(--trim) 65%, transparent);
    }

    [data-sheet-style='thornwood'] [data-slot='tag-list'] > * + * {
        border-top-color: color-mix(in oklab, var(--trim) 32%, transparent);
    }

    [data-sheet-style='thornwood'] [data-slot='card-footer'] {
        border-top-color: color-mix(in oklab, var(--trim) 50%, transparent);
    }

    /* An empty box is the setting the stone has not been put in yet. */
    [data-sheet-style='thornwood'] [data-slot='track-pip'] {
        border-color: color-mix(in oklab, var(--trim) 45%, transparent);
        background-color: transparent;
    }

    /*
     * A filled one is the stone. The box is already a square turned on its point, so a facet
     * running corner to corner is all it takes to read as cut: a lit face, a hard line down
     * the middle, and a darker one beneath.
     */
    [data-sheet-style='thornwood'] [data-slot='track-pip'][data-filled] {
        border-color: color-mix(in oklab, var(--trim) 75%, black);
        background-color: var(--trim);
        background-image: linear-gradient(
            135deg,
            color-mix(in oklab, var(--trim) 55%, white) 0%,
            var(--trim) 46%,
            color-mix(in oklab, var(--trim) 60%, black) 54%,
            color-mix(in oklab, var(--trim) 85%, black) 100%
        );
        box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.18); box-shadow: inset 0 0 0 1px oklch(from var(--tw-sheen) l c h / 0.18);
    }

    /* Amethyst is a stone rather than a metal, so it keeps a little light inside it. */
    [data-sheet-style='thornwood'] [data-card-rank='3'] [data-slot='track-pip'][data-filled] {
        box-shadow:
            inset 0 0 0 1px rgb(255 255 255 / 0.22),
            inset 0 0 4px rgb(220 174 254 / 0.75); box-shadow:
            inset 0 0 0 1px oklch(from var(--tw-sheen) l c h / 0.22),
            inset 0 0 4px oklch(from var(--tw-amethyst-light) l c h / 0.75);
    }

    /* ---------------------------------------------------------------------- lettering */
    [data-sheet-style='thornwood'] [data-slot='card-title'],
    [data-sheet-style='thornwood'] [data-slot='card-kind-label'],
    [data-sheet-style='thornwood'] [data-slot='wordmark'] {
        font-family: var(--font-display);
    }

    [data-sheet-style='thornwood'] [data-slot='card-title'] {
        /*
         * A touch smaller than the default the whole way up the ramp, to win back the line
         * the printed mat cost.
         *
         * A ratio rather than a clamp of its own, so "the whole way up" stays true: a length
         * here would keep its own ceiling and quietly stop tracking the default once a card
         * grew past the width the number was picked at.
         */
        --card-title-size: calc(var(--card-text) * 1.5);
        letter-spacing: 0.01em;
    }

    [data-sheet-style='thornwood'] [data-slot='card-kind-label'] {
        color: var(--tw-lichen);
        letter-spacing: 0.22em;
    }

    /* The bar down a weakness's left edge. Its wash and ink are set on the card, above. */
    [data-sheet-style='thornwood'] [data-form='card'] [data-tag-kind='weakness'] {
        box-shadow: inset 2px 0 0 var(--tw-thorn);
    }

    [data-sheet-style='thornwood'] [data-slot='card-footer'] {
        background-color: rgb(153 130 101 / 0.14); background-color: oklch(from var(--tw-umber) l c h / 0.14);
    }

    [data-sheet-style='thornwood'] [data-slot='pull-hint'] {
        border: 1px solid rgb(141 106 67 / 0.5); border: 1px solid oklch(from var(--tw-bronze) l c h / 0.5);
        background-color: rgb(237 231 219 / 0.92); background-color: oklch(from var(--tw-vellum-light) l c h / 0.92);
        font-family: var(--font-display);
        letter-spacing: 0.06em;
    }

    /* ------------------------------------------------------------------ status cards */
    /*
     * Statuses are the creepiest thing on the sheet, so they get an uneven hand-cut edge,
     * a double rule, and a faint glow as though something is still living in them.
     */
    [data-sheet-style='thornwood'] [data-slot='status-card'] {
        border-color: var(--tw-moss);
        border-style: double;
        border-width: 3px;
        border-radius: 14px 5px 13px 6px / 6px 13px 5px 14px;
        background-color: var(--tw-bark-lit);
        background-image: radial-gradient(
            90% 120% at 12% 0%,
            rgb(28 50 26 / 0.85),
            transparent 70%
        ); background-image: radial-gradient(
            90% 120% at 12% 0%,
            oklch(from var(--tw-moss-deep) l c h / 0.85),
            transparent 70%
        );
        box-shadow:
            0 0 14px rgb(101 149 90 / 0.3),
            0 2px 10px rgb(0 2 1 / 0.6); box-shadow:
            0 0 14px oklch(from var(--tw-glow) l c h / 0.3),
            0 2px 10px oklch(from var(--tw-shadow) l c h / 0.6);
        color: var(--tw-lichen);
    }

    [data-sheet-style='thornwood'] [data-slot='status-card'] input,
    [data-sheet-style='thornwood'] [data-slot='status-card'] span {
        color: var(--tw-lichen);
    }

    /* -------------------------------------------------------------- chrome and the tray */
    [data-sheet-style='thornwood'] [data-slot='top-bar'] {
        border-bottom: 1px solid rgb(51 87 53 / 0.4); border-bottom: 1px solid oklch(from var(--tw-moss) l c h / 0.4);
    }

    [data-sheet-style='thornwood'] [data-slot='wordmark'] {
        color: var(--tw-lichen);
        letter-spacing: 0.04em;
        text-shadow: 0 0 14px rgb(101 149 90 / 0.4); text-shadow: 0 0 14px oklch(from var(--tw-glow) l c h / 0.4);
    }

    [data-sheet-style='thornwood'] [data-slot='menu'] {
        border-right-color: rgb(51 87 53 / 0.55); border-right-color: oklch(from var(--tw-moss) l c h / 0.55);
        background-color: var(--tw-menu);
        background-image:
            linear-gradient(
                to right,
                rgb(28 50 26 / 0.35),
                transparent 45%
            ),
            radial-gradient(
                80% 30% at 20% 0%,
                rgb(51 87 53 / 0.4),
                transparent 70%
            ); background-image:
            linear-gradient(
                to right,
                oklch(from var(--tw-moss-deep) l c h / 0.35),
                transparent 45%
            ),
            radial-gradient(
                80% 30% at 20% 0%,
                oklch(from var(--tw-moss) l c h / 0.4),
                transparent 70%
            );
        color: var(--tw-lichen);
    }

    [data-sheet-style='thornwood'] [data-slot='menu'] a,
    [data-sheet-style='thornwood'] [data-slot='menu'] button {
        border-radius: 2px 9px 3px 8px / 8px 3px 9px 2px;
    }

    [data-sheet-style='thornwood'] [data-slot='menu'] a:hover,
    [data-sheet-style='thornwood'] [data-slot='menu'] button:hover:enabled {
        background-color: rgb(28 50 26 / 0.5); background-color: oklch(from var(--tw-moss-deep) l c h / 0.5);
        box-shadow: inset 2px 0 0 var(--tw-moss);
    }

    /* A burnt tag should look like it is still smouldering. */
    [data-sheet-style='thornwood'] [aria-pressed='true'] > .lucide-flame {
        filter: drop-shadow(0 0 6px rgb(236 125 0 / 0.8)); filter: drop-shadow(0 0 6px oklch(from var(--tw-ember) l c h / 0.8));
    }

    /*
     * The severity track was the last stark-white thing on the sheet. Marked tiers become
     * lichen on bark; unmarked ones are barely there.
     */
    [data-sheet-style='thornwood'] [data-slot='status-card'] [aria-label^='Severity'] {
        border-color: rgb(51 87 53 / 0.6); border-color: oklch(from var(--tw-moss) l c h / 0.6);
        border-radius: 5px 3px 6px 3px;
        color: var(--tw-lichen-dim);
    }

    [data-sheet-style='thornwood'] [data-slot='status-card'] [aria-label^='Severity'][aria-pressed='true'] {
        border-color: var(--tw-lichen);
        background-color: var(--tw-glow);
        color: var(--tw-menu);
    }

    /* The theme type sits under the might, in the same face but held back. */
    [data-sheet-style='thornwood'] [data-slot='card-meta'] {
        font-family: var(--font-display);
        color: rgb(95 83 70 / 0.8); color: oklch(from var(--paper-ink-muted) l c h / 0.8);
        letter-spacing: 0.08em;
    }

    /* Rules either side of the might, the way a tarot card titles itself. */
    [data-sheet-style='thornwood'] [data-slot='card-kind-label'] {
        display: flex;
        align-items: center;
        gap: 0.6rem;
        color: var(--tw-bronze);
    }

    [data-sheet-style='thornwood'] [data-slot='card-kind-label']::before,
    [data-sheet-style='thornwood'] [data-slot='card-kind-label']::after {
        content: '';
        width: 1.4rem;
        height: 1px;
        background-color: rgb(141 106 67 / 0.6); background-color: oklch(from var(--tw-bronze) l c h / 0.6);
    }

    /* ------------------------------------------------------------- the pages around the sheet */
    /*
     * Everything below dresses the app *outside* the deck — logging in, choosing a
     * character, making a party. None of it needed a new hook: those pages are built from
     * the same surface, card, top bar and menu the
     * sheet is, so the forest floor, the parchment and the corner brackets arrived on them
     * for free. What is left is the handful of things only a form has.
     */
    /*
     * A field is a ruled line on the paper, so it takes the ink colour, not the UI border.
     *
     * Split by what the line is ruled on. Almost every field in the app is inside a card, but
     * a few are not — the address you invite somebody to a party with sits straight on the
     * forest floor, and ink mixed for parchment is invisible on bark. The treatment is the
     * same argument either way: writing takes the colour of the thing written on, which off
     * the card is lichen.
     */
    [data-sheet-style='thornwood'] [data-slot='paper-field'] {
        font-family: var(--font-body);
    }

    [data-sheet-style='thornwood'] [data-form='card'] [data-slot='paper-field'] {
        border-bottom-color: rgb(141 106 67 / 0.55); border-bottom-color: oklch(from var(--tw-bronze) l c h / 0.55);
    }

    [data-sheet-style='thornwood'] [data-form='card'] [data-slot='paper-field']:focus {
        border-bottom-color: var(--tw-bronze-deep);
        /* A wash of ink where the nib is resting, light enough to read as damp paper. */
        background-color: rgb(153 130 101 / 0.07); background-color: oklch(from var(--tw-umber) l c h / 0.07);
    }

    [data-sheet-style='thornwood'] [data-form='card'] [data-slot='paper-field']::placeholder {
        color: rgb(95 83 70 / 0.65); color: oklch(from var(--paper-ink-muted) l c h / 0.65);
        font-style: italic;
    }

    [data-sheet-style='thornwood'] [data-slot='paper-field']:not([data-form='card'] *) {
        border-bottom-color: rgb(51 87 53 / 0.55); border-bottom-color: oklch(from var(--tw-moss) l c h / 0.55);
        color: var(--tw-lichen);
    }

    [data-sheet-style='thornwood'] [data-slot='paper-field']:not([data-form='card'] *):focus {
        border-bottom-color: var(--tw-glow);
        /* The same wash, mixed for moss instead of for paper. */
        background-color: rgb(101 149 90 / 0.12); background-color: oklch(from var(--tw-glow) l c h / 0.12);
    }

    [data-sheet-style='thornwood'] [data-slot='paper-field']:not([data-form='card'] *)::placeholder {
        color: rgb(169 193 146 / 0.55); color: oklch(from var(--tw-lichen) l c h / 0.55);
        font-style: italic;
    }

    /* Buttons on a card are pressed into the paper rather than floated over it. */
    [data-sheet-style='thornwood'] [data-form='card'] button,
    [data-sheet-style='thornwood'] [data-form='card'] a[class*='rounded-full'] {
        font-family: var(--font-display);
        letter-spacing: 0.06em;
    }

    /*
     * The rules either side of a card's kind label are drawn with pseudo-elements, so a
     * label that is a party name rather than a card type still gets them. Long ones would
     * otherwise push the rules off the card.
     */
    [data-sheet-style='thornwood'] [data-slot='card-kind-label'] {
        max-width: 100%;
        text-align: center;
        text-wrap: balance;
    }

    /*
     * The page's own title and the rules between sections sit on the bark, not on paper —
     * so they take the lichen, while a card's title keeps its ink.
     *
     * Both are their own slots for exactly that reason: an earlier pass styled `main h1, h2`
     * and turned every card title on the page green, because a card's title is an h2 too.
     * Styles get hooks, never structure.
     */
    [data-sheet-style='thornwood'] [data-slot='page-title'],
    [data-sheet-style='thornwood'] [data-slot='section-rule'] {
        font-family: var(--font-display);
        color: var(--tw-lichen-dim);
        letter-spacing: 0.16em;
    }

    /*
     * A panel is the cloth a reading is laid on, not a box: velvet, piped in bronze. Opaque,
     * because moss showing through it is exactly what made it hard to read off. The picture
     * is a knob — `panel-texture` — and the piping is drawn inside the edge, in the padding.
     */
    [data-sheet-style='thornwood'] [data-slot='section'] {
        background-color: var(--tw-velvet);
        background-blend-mode: normal, overlay;
        border-color: rgb(141 106 67 / 0.8); border-color: oklch(from var(--tw-bronze) l c h / 0.8);
        box-shadow:
            inset 0 0 0 3px rgb(5 12 6 / 0.55),
            inset 0 0 0 4px rgb(141 106 67 / 0.9),
            inset 0 0 2rem rgb(5 12 6 / 0.55),
            0 0.4rem 1rem rgb(5 12 6 / 0.6); box-shadow:
            inset 0 0 0 3px oklch(from var(--surface) l c h / 0.55),
            inset 0 0 0 4px oklch(from var(--tw-bronze) l c h / 0.9),
            inset 0 0 2rem oklch(from var(--surface) l c h / 0.55),
            0 0.4rem 1rem oklch(from var(--surface) l c h / 0.6);
    }

    /*
     * On the velvet, moss is the wrong colour for the one that is open — it is the forest's,
     * not the cloth's. The pile brushed up instead, with a thread of bronze round it; and the
     * headings take the bronze of the piping rather than the lichen of the floor.
     */
    [data-sheet-style='thornwood'] main [data-slot='section'] :is(a, button)[class*='bg-primary']:not([data-form='card'] *) {
        background-color: var(--tw-velvet-lit);
        box-shadow: inset 0 0 0 1px rgb(141 106 67 / 0.5); box-shadow: inset 0 0 0 1px oklch(from var(--tw-bronze) l c h / 0.5);
    }

    [data-sheet-style='thornwood'] [data-slot='section'] [data-slot='section-rule'] {
        color: rgb(242 200 156 / 0.75); color: oklch(from var(--tw-bronze-light) l c h / 0.75);
    }

    /*
     * EB Garamond's figures are old-style: its 4 descends and opens at the top, which at
     * 10px under 0.18em of tracking reads as a "+". Lining figures are what a printed card
     * would set a count in anyway.
     */
    [data-sheet-style='thornwood'] {
        font-variant-numeric: lining-nums;
    }

    /*
     * Anything sitting straight on the forest floor — the roster's actions, a form's submit
     * row — rather than on a card. The `:not()` keeps it off everything inside one, and off
     * paper that is not a card: a control panel is written on in the paper's ink.
     *
     * An outline button is a shape cut out of the dark and takes lichen. A filled one is the
     * style's action colour already.
     */
    [data-sheet-style='thornwood'] main :is(a, button)[class*='rounded-full']:not([data-form='card'] *) {
        font-family: var(--font-display);
        letter-spacing: 0.05em;
    }

    [data-sheet-style='thornwood'] main
        :is(a, button)[class*='rounded-full']:not(
            [data-form='card'] *,
            [data-paper] *,
            [class*='bg-primary']
        ) {
        border-color: rgb(51 87 53 / 0.6); border-color: oklch(from var(--tw-moss) l c h / 0.6);
        color: var(--tw-lichen);
    }

    /*
     * Settings tabs and the roster's actions sit on the forest floor rather than on a card,
     * so they need the lichen treatment the cards' own text does not.
     */
    [data-sheet-style='thornwood'] main nav[aria-label='Settings'] {
        border-bottom-color: rgb(51 87 53 / 0.4); border-bottom-color: oklch(from var(--tw-moss) l c h / 0.4);
    }

    [data-sheet-style='thornwood'] main nav[aria-label='Settings'] a {
        font-family: var(--font-display);
        color: var(--tw-lichen-dim);
    }

    [data-sheet-style='thornwood'] main nav[aria-label='Settings'] a[aria-current='page'] {
        background-color: rgb(28 50 26 / 0.55); background-color: oklch(from var(--tw-moss-deep) l c h / 0.55);
        color: var(--tw-lichen);
    }

    /* ---------------------------------------------------------------------- portraits */
    /*
     * A face in Thornwood is a face in the hedge.
     *
     * This is the first thing a style does to a *picture* rather than to paper, and it is
     * deliberately the whole treatment rather than a tint: a wreath grown around the frame,
     * the light pulled green and low, and the picture sunk into the card instead of laid on
     * top of it. Light and dark leave portraits alone, which is the point of comparison.
     *
     * The front end gives three hooks and no styling worth speaking of:
     *
     *   character-portrait — the outer element, never clipped, for ornament that overflows
     *   portrait-frame     — the circle the picture is clipped to
     *   portrait-backdrop  — the portrait printed into a roster card
     */
    [data-sheet-style='thornwood'] [data-slot='character-portrait']::after {
        content: '';
        position: absolute;
        /* Outside the frame on every side: the wreath is grown around it, not drawn on it. */
        inset: -19%;
        background: url('/storage/production/styles/thornwood/wreath-064afac8.svg') center / contain no-repeat;
        pointer-events: none;
        /* Turned slightly off true so it never reads as a printed border. */
        transform: rotate(-4deg);
    }

    [data-sheet-style='thornwood'] [data-slot='portrait-frame'] {
        border-color: var(--tone-plain-edge);
        /*
         * Sunk rather than mounted: a dark rim inside the circle, heavier along the bottom
         * the way something resting in a bowl catches less light.
         */
        box-shadow:
            inset 0 0 14px rgb(28 50 26 / 0.55),
            inset 0 -9px 18px rgb(28 50 26 / 0.5); mounted: a dark rim inside the circle, heavier along the bottom
         * the way something resting in a bowl catches less light.
         */
        box-shadow:
            inset 0 0 14px oklch(from var(--tw-moss-deep) l c h / 0.55),
            inset 0 -9px 18px oklch(from var(--tw-moss-deep) l c h / 0.5);
    }

    [data-sheet-style='thornwood'] [data-slot='portrait-frame'] img {
        /*
         * Pulled towards the card's own greens so a photograph taken in a bright room stops
         * looking like a photograph taken in a bright room.
         */
        filter: sepia(0.4) saturate(0.85) hue-rotate(28deg) contrast(1.06)
            brightness(0.94);
    }

    /* The roster card's portrait gets the same light, and a little more fog. */
    [data-sheet-style='thornwood'] [data-slot='portrait-backdrop'] {
        opacity: 0.82;
        filter: sepia(0.35) saturate(0.8) hue-rotate(26deg) brightness(0.9);
    }

    /* ------------------------------------------------- the storyteller's table */
    /*
     * A dark slab of a table with something growing at its edges, and chairs cut from the
     * same wood. The room is the one place on this style with real empty space in the middle
     * of it, so the glow is kept low — it is a surface to read across, not another card.
     */
    [data-sheet-style='thornwood'] [data-slot='table-top'] {
        border-color: rgb(51 87 53 / 0.6); border-color: oklch(from var(--tw-moss) l c h / 0.6);
        background-color: var(--tw-bark);
        background-image: radial-gradient(
            70% 70% at 50% 40%,
            rgb(28 50 26 / 0.7),
            transparent 75%
        ); background-image: radial-gradient(
            70% 70% at 50% 40%,
            oklch(from var(--tw-moss-deep) l c h / 0.7),
            transparent 75%
        );
        box-shadow: inset 0 0 30px rgb(0 2 1 / 0.7); box-shadow: inset 0 0 30px oklch(from var(--tw-shadow) l c h / 0.7);
    }

    [data-sheet-style='thornwood'] [data-slot='table-seat'] {
        color: var(--tw-lichen);
    }

    [data-sheet-style='thornwood'] [data-slot='table-seat'][data-occupied] {
        background-color: var(--tw-bark-lit);
        box-shadow: 0 0 12px rgb(101 149 90 / 0.25); box-shadow: 0 0 12px oklch(from var(--tw-glow) l c h / 0.25);
    }

    [data-sheet-style='thornwood'] [data-slot='seat-portrait'] {
        border: 1px solid rgb(51 87 53 / 0.6); border: 1px solid oklch(from var(--tw-moss) l c h / 0.6);
    }

    /* The storyteller's own place, marked rather than seated. */
    [data-sheet-style='thornwood'] [data-slot='table-seat'][data-storyteller] {
        border-color: rgb(51 87 53 / 0.7); border-color: oklch(from var(--tw-moss) l c h / 0.7);
        color: var(--tw-lichen);
        text-shadow: 0 0 12px rgb(101 149 90 / 0.4); text-shadow: 0 0 12px oklch(from var(--tw-glow) l c h / 0.4);
    }

    /* A status handed over glows the way the cards in the pocket already do. */
    [data-sheet-style='thornwood'] [data-arrived] [data-slot='status-grip'] {
        outline-color: var(--tw-glow);
    }

    /* ------------------------------------------------------------------- someone else here */
    /*
     * Thornwood does not draw a ring round a row somebody else is writing in. It puts a
     * token down on it — a carved disc with their face on it, hung off the corner and set at
     * whatever angle the hand happened to hold it.
     *
     * `--editor-tilt` is the angle, and the component sets it per placement: the same person
     * moving to another row is the token being picked up and put down again, so it lands
     * differently. Nothing here rolls it; a value rolled in CSS would be re-rolled on every
     * repaint and the token would shiver.
     */
    [data-sheet-style='thornwood'] [data-slot='editors-here'][data-presence='token'] {
        top: -0.9rem;
        right: 0.35rem;
        gap: 0.15rem;
    }

    [data-sheet-style='thornwood'] [data-slot='editor-token'] {
        width: 1.75rem;
        height: 1.75rem;
        rotate: var(--editor-tilt, 0deg);
        background-color: var(--tw-bark);
        /*
         * The rim takes its hue from the person. `color` is the per-editor colour the
         * component put on as a utility and is deliberately left alone, so this file never
         * has to know how many people the palette runs to.
         */
        border: 2px solid color-mix(in oklab, currentColor 55%, var(--tw-bark));
        /* Sitting proud of the card: a rim of light on top, and its shadow on the paper.
           Also what replaces the ring the default presentation draws. */
        box-shadow:
            inset 0 1px 0 rgb(101 149 90 / 0.45),
            inset 0 -2px 3px rgb(0 2 1 / 0.6),
            0 3px 5px rgb(0 2 1 / 0.55); card: a rim of light on top, and its shadow on the paper.
           Also what replaces the ring the default presentation draws. */
        box-shadow:
            inset 0 1px 0 oklch(from var(--tw-glow) l c h / 0.45),
            inset 0 -2px 3px oklch(from var(--tw-shadow) l c h / 0.6),
            0 3px 5px oklch(from var(--tw-shadow) l c h / 0.55);
    }

    /*
     * A card clips its own corners, so the token on a card's own fields is laid just inside
     * the frame rather than hung off it. The rows printed on the card are further in and
     * keep the overhang.
     */
    [data-sheet-style='thornwood'] [data-form='card'] > [data-slot='editors-here'] {
        top: 0.35rem;
    }

    /* Faces on this style are lit by the same low green as everything else. */
    [data-sheet-style='thornwood'] [data-slot='editor-face'] {
        filter: saturate(0.75) contrast(1.05) brightness(0.92) sepia(0.15)
            hue-rotate(50deg);
    }

    /*
     * How the token gets there, and there are two ways.
     *
     * A token nobody had down yet is *placed*: it arrives a little large and off to the side
     * and settles, which is what a hand putting one down looks like. A token that was already
     * on the sheet is *slid*: it travels from wherever it was, turning as it goes, because a
     * token being moved is not a second token being produced.
     *
     * The component measures the journey and hands over the two offsets and the angle it
     * left at. Which of the two it is, is `data-arrived`.
     */
    @media (prefers-reduced-motion: no-preference) {
        [data-sheet-style='thornwood'] [data-slot='editor-token'][data-arrived='placed'] {
            animation: thornwood-token-placed 220ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
        }
        [data-sheet-style='thornwood'] [data-slot='editor-token'][data-arrived='slid'] {
            animation: thornwood-token-slid 320ms cubic-bezier(0.32, 0.72, 0.24, 1);
        }
    }

    /* ------------------------------------------------------------------------ the table */
    /*
     * The party's table, looked up at from a player's sheet: a sheet of vellum laid on the
     * forest floor, vines grown round its edge and a knot in the middle of it.
     *
     * ⚠️ Both pictures are placeholders — `table-vines.svg` and `table-sigil.svg` — drawn to
     * have something in the slots, not to be kept.
     *
     * The front end gives four hooks, all under the cards and all turning with the table:
     *
     *   seat-view         — the room around it
     *   table-frame       — its edge, never clipped
     *   table-surface     — what the cards lie on, clipped
     *   table-centrepiece — an empty square in the middle of the surface
     */
    [data-sheet-style='thornwood'] [data-slot='seat-view'] {
        background-color: var(--surface);
        background-image: var(--surface-texture);
        background-blend-mode: soft-light, screen, screen, normal;
    }

    [data-sheet-style='thornwood'] [data-slot='table-frame'] {
        border-radius: 0.5rem;
        /* Lying on the moss rather than floating over it: a short, dark shadow. */
        box-shadow: 0 6px 18px rgb(0 2 1 / 0.85); it: a short, dark shadow. */
        box-shadow: 0 6px 18px oklch(from var(--tw-shadow) l c h / 0.85);
    }

    /*
     * The vines. `::after` so they lie over the edge of the vellum, and under the cards — the
     * cards are drawn after the frame. Nine-sliced: the corners once, each side's middle
     * repeated round until it fits, so any shape of screen gets a whole number of leaves.
     * The inset is half the band, which runs the stem along the vellum's very edge.
     */
    [data-sheet-style='thornwood'] [data-slot='table-frame']::after {
        content: '';
        position: absolute;
        inset: -14px;
        border: 28px solid transparent;
        border-image: url('/storage/production/styles/thornwood/table-vines-dbda048e.svg') 40 round;
        pointer-events: none;
    }

    [data-sheet-style='thornwood'] [data-slot='table-surface'] {
        background-color: var(--paper);
        background-image:
            var(--paper-texture),
            radial-gradient(
                120% 110% at 50% 50%,
                transparent 55%,
                rgb(153 130 101 / 0.35) 100%
            ); background-image:
            var(--paper-texture),
            radial-gradient(
                120% 110% at 50% 50%,
                transparent 55%,
                oklch(from var(--tw-umber) l c h / 0.35) 100%
            );
    }

    [data-sheet-style='thornwood'] [data-slot='table-centrepiece'] {
        background: url('/storage/production/styles/thornwood/table-sigil-aefa0b2e.svg') center / contain no-repeat;
        /* Worked into the vellum, not set on it: faint enough to read a card over. */
        opacity: 0.5;
    }

    /*
     * A player's marker: a place card cut from the same vellum as the cards, rimmed in bronze,
     * the face sunk into it the way a portrait is on the sheet, the name in the display hand.
     */
    [data-sheet-style='thornwood'] [data-slot='seat-marker'] {
        border-color: var(--tone-plain-edge);
        border-radius: 0.5rem;
        background-color: var(--paper);
        background-image: var(--paper-texture);
        color: var(--paper-ink);
        box-shadow:
            0 1px 0 rgb(255 255 255 / 0.35) inset,
            0 3px 8px rgb(0 2 1 / 0.7); box-shadow:
            0 1px 0 oklch(from var(--tw-sheen) l c h / 0.35) inset,
            0 3px 8px oklch(from var(--tw-shadow) l c h / 0.7);
    }

    [data-sheet-style='thornwood'] [data-slot='marker-portrait'] {
        border: 2px solid var(--rank-1-trim);
        background-color: var(--tw-moss);
        color: var(--tw-lichen);
        box-shadow: inset 0 3px 8px rgb(0 2 1 / 0.6); box-shadow: inset 0 3px 8px oklch(from var(--tw-shadow) l c h / 0.6);
    }

    [data-sheet-style='thornwood'] [data-slot='marker-name'] {
        font-family: var(--font-display);
        font-weight: 400;
    }
}
