Signature Library · Indian
Inland Letter
A blue folded post office letter; lift the flap to read inside.
States
Default
Hover
Active
Focus
Code
inland-letter.html
<div class="sig-inland-letter" data-shut="Close">
<p class="sig-inland-letter__message">Dear Amma, reached safely. The job is good. Will come for Pongal.</p>
<button class="sig-inland-letter__cover" type="button" aria-expanded="false">
<span class="sig-inland-letter__kind">Inland Letter</span>
<span class="sig-inland-letter__stamp" aria-hidden="true">₹2.50</span>
<span class="sig-inland-letter__to">To, Amma</span>
<span class="sig-inland-letter__open" data-word>Open</span>
</button>
</div>
inland-letter.css
.sig-inland-letter {
--sig-paper: #a9c7e8;
--sig-ink: #1d2f5e;
--sig-w: 290px;
--sig-speed: 420ms;
}
.sig-inland-letter {
position: relative;
box-sizing: border-box;
width: var(--sig-w);
max-width: 100%;
height: 150px;
perspective: 700px;
font-family: Georgia, 'Times New Roman', serif;
color: var(--sig-ink);
}
.sig-inland-letter[data-state=open] {
--lift: 76deg;
}
.sig-inland-letter__message {
position: absolute;
inset: 0;
margin: 0;
padding: 14px 16px;
box-sizing: border-box;
font-size: 14px;
line-height: 23px;
overflow: auto;
background: repeating-linear-gradient(180deg, transparent 0 22px, color-mix(in srgb, var(--sig-ink) 18%, transparent) 22px 23px), color-mix(in srgb, var(--sig-paper) 45%, #fff);
border-radius: 2px;
}
.sig-inland-letter__cover {
position: absolute;
inset: 0;
display: block;
width: 100%;
padding: 10px 14px;
color: inherit;
font: inherit;
text-align: left;
background: linear-gradient(180deg, rgba(255,255,255,.2), transparent 12%), var(--sig-paper);
border: 0;
border-bottom: 2px dashed color-mix(in srgb, var(--sig-ink) 45%, transparent);
border-radius: 2px;
box-shadow: 0 4px 10px rgba(0,0,0,.3);
cursor: pointer;
transform-origin: 50% 0;
transform: rotateX(var(--lift, 0deg));
transition: transform var(--sig-speed) ease;
}
.sig-inland-letter__cover:focus-visible {
outline: 2px solid var(--sig-ink);
outline-offset: -5px;
}
.sig-inland-letter__kind {
display: block;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.sig-inland-letter__stamp {
position: absolute;
top: 10px;
right: 12px;
width: 46px;
height: 54px;
display: grid;
place-items: center;
font-size: 11px;
font-weight: 700;
text-align: center;
color: var(--sig-paper);
background: var(--sig-ink);
outline: 3px dotted color-mix(in srgb, var(--sig-paper) 55%, #fff);
outline-offset: -2px;
}
.sig-inland-letter__to {
display: block;
margin-top: 28px;
font-size: 15px;
font-style: italic;
}
.sig-inland-letter__open {
position: absolute;
bottom: 8px;
right: 14px;
font-size: 11px;
font-weight: 700;
font-family: system-ui, sans-serif;
text-decoration: underline;
}
@media (prefers-reduced-motion: reduce) {
.sig-inland-letter__cover {
animation: none !important;
transition: none !important;
}
}
inland-letter.js
document.querySelectorAll(".sig-inland-letter").forEach((el) => {
const flap = el.querySelector("[aria-expanded]");
const word = flap.querySelector("[data-word]");
const closed = word.textContent;
const flip = () => {
const open = flap.getAttribute("aria-expanded") !== "true";
flap.setAttribute("aria-expanded", String(open));
el.dataset.state = open ? "open" : "shut";
word.textContent = open ? el.dataset.shut ?? "" : closed;
};
flap.addEventListener("click", flip);
return () => flap.removeEventListener("click", flip);
});
inland-letter.tsx
import { useEffect, useRef } from "react";
import type React from "react";
import "./inland-letter.css"; // the CSS tab
function attach(el: HTMLElement) {
const flap = el.querySelector("[aria-expanded]") as HTMLElement;
const word = flap.querySelector("[data-word]") as HTMLElement;
const closed = word.textContent;
const flip = () => {
const open = flap.getAttribute("aria-expanded") !== "true";
flap.setAttribute("aria-expanded", String(open));
el.dataset.state = open ? "open" : "shut";
word.textContent = open ? el.dataset.shut ?? "" : closed;
};
flap.addEventListener("click", flip);
return () => flap.removeEventListener("click", flip);
}
export function SigInlandLetter({ children = "Inland Letter", ...props }: React.ComponentProps<"div">) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => attach(ref.current!), []);
return (
<div className="sig-inland-letter" data-shut="Close" ref={ref} {...props}>
<p className="sig-inland-letter__message">{"Dear Amma, reached safely. The job is good. Will come for Pongal."}</p>
<button className="sig-inland-letter__cover" type="button" aria-expanded="false">
<span className="sig-inland-letter__kind">{children}</span>
<span className="sig-inland-letter__stamp" aria-hidden="true">{"₹2.50"}</span>
<span className="sig-inland-letter__to">{"To, Amma"}</span>
<span className="sig-inland-letter__open" data-word>{"Open"}</span>
</button>
</div>
);
}
inland-letter.html
<div class="sig-inland-letter relative [box-sizing:border-box] w-[290px] [max-width:100%] h-[150px] [perspective:700px] [font-family:Georgia,_'Times_New_Roman',_serif] text-[#1d2f5e] [&[data-state=open]]:[--lift:76deg]" data-shut="Close">
<p class="absolute [inset:0] [margin:0] [padding:14px_16px] [box-sizing:border-box] text-[14px] [line-height:23px] [overflow:auto] [background:repeating-linear-gradient(180deg,_transparent_0_22px,_color-mix(in_srgb,_#1d2f5e_18%,_transparent)_22px_23px),_color-mix(in_srgb,_#a9c7e8_45%,_#fff)] rounded-[2px]">Dear Amma, reached safely. The job is good. Will come for Pongal.</p>
<button class="absolute [inset:0] [display:block] w-[100%] [padding:10px_14px] [color:inherit] [font:inherit] [text-align:left] [background:linear-gradient(180deg,_rgba(255,255,255,.2),_transparent_12%),_#a9c7e8] [border:0] [border-bottom:2px_dashed_color-mix(in_srgb,_#1d2f5e_45%,_transparent)] rounded-[2px] [box-shadow:0_4px_10px_rgba(0,0,0,.3)] cursor-pointer [transform-origin:50%_0] [transform:rotateX(var(--lift,_0deg))] [transition:transform_420ms_ease] focus-visible:[outline:2px_solid_#1d2f5e] focus-visible:[outline-offset:-5px] motion-reduce:[transition:none!important]" type="button" aria-expanded="false">
<span class="[display:block] text-[11px] font-[700] [letter-spacing:0.14em] [text-transform:uppercase]">Inland Letter</span>
<span class="absolute [top:10px] [right:12px] w-[46px] h-[54px] grid [place-items:center] text-[11px] font-[700] [text-align:center] text-[#a9c7e8] bg-[#1d2f5e] [outline:3px_dotted_color-mix(in_srgb,_#a9c7e8_55%,_#fff)] [outline-offset:-2px]" aria-hidden="true">₹2.50</span>
<span class="[display:block] [margin-top:28px] text-[15px] [font-style:italic]">To, Amma</span>
<span class="absolute [bottom:8px] [right:14px] text-[11px] font-[700] [font-family:system-ui,_sans-serif] [text-decoration:underline]" data-word>Open</span>
</button>
</div>
<!-- Needs the script from the JS tab. -->