Month View

Calendar showing a month.

August 2026
SunMonTueWed ThuFriSat
(today)

html

<table class="mv" data-density="Comfortable" data-weekend="true" style="--accent:#A8E6C1;">
  <caption class="mv__caption">August 2026</caption>
  <thead>
    <tr>
      <th scope="col">Sun</th><th scope="col">Mon</th><th scope="col">Tue</th><th scope="col">Wed</th>
      <th scope="col">Thu</th><th scope="col">Fri</th><th scope="col">Sat</th>
    </tr>
  </thead>
  <tbody>
    <tr><td class="mv__cell mv__cell--dim"><time datetime="2026-07-26">26</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-07-27">27</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-07-28">28</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-07-29">29</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-07-30">30</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-07-31">31</time></td><td class="mv__cell"><time datetime="2026-08-01">1</time></td></tr>
    <tr><td class="mv__cell"><time datetime="2026-08-02">2</time></td><td class="mv__cell"><time datetime="2026-08-03">3</time></td><td class="mv__cell"><time datetime="2026-08-04">4</time></td><td class="mv__cell mv__cell--event"><time datetime="2026-08-05">5</time><span class="mv__event-dot" aria-hidden="true"></span></td><td class="mv__cell"><time datetime="2026-08-06">6</time></td><td class="mv__cell"><time datetime="2026-08-07">7</time></td><td class="mv__cell"><time datetime="2026-08-08">8</time></td></tr>
    <tr><td class="mv__cell"><time datetime="2026-08-09">9</time></td><td class="mv__cell mv__cell--selected" aria-current="date"><time datetime="2026-08-10">10</time></td><td class="mv__cell"><time datetime="2026-08-11">11</time></td><td class="mv__cell mv__cell--event"><time datetime="2026-08-12">12</time><span class="mv__event-dot" aria-hidden="true"></span></td><td class="mv__cell"><time datetime="2026-08-13">13</time></td><td class="mv__cell"><time datetime="2026-08-14">14</time></td><td class="mv__cell"><time datetime="2026-08-15">15</time></td></tr>
    <tr><td class="mv__cell"><time datetime="2026-08-16">16</time></td><td class="mv__cell"><time datetime="2026-08-17">17</time></td><td class="mv__cell mv__cell--today"><time datetime="2026-08-18">18</time><span class="mv__today-dot" aria-hidden="true"></span><span class="sr-only"> (today)</span></td><td class="mv__cell"><time datetime="2026-08-19">19</time></td><td class="mv__cell mv__cell--event"><time datetime="2026-08-20">20</time><span class="mv__event-dot" aria-hidden="true"></span></td><td class="mv__cell"><time datetime="2026-08-21">21</time></td><td class="mv__cell"><time datetime="2026-08-22">22</time></td></tr>
    <tr><td class="mv__cell"><time datetime="2026-08-23">23</time></td><td class="mv__cell"><time datetime="2026-08-24">24</time></td><td class="mv__cell"><time datetime="2026-08-25">25</time></td><td class="mv__cell"><time datetime="2026-08-26">26</time></td><td class="mv__cell mv__cell--event"><time datetime="2026-08-27">27</time><span class="mv__event-dot" aria-hidden="true"></span></td><td class="mv__cell"><time datetime="2026-08-28">28</time></td><td class="mv__cell"><time datetime="2026-08-29">29</time></td></tr>
    <tr><td class="mv__cell"><time datetime="2026-08-30">30</time></td><td class="mv__cell"><time datetime="2026-08-31">31</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-09-01">1</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-09-02">2</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-09-03">3</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-09-04">4</time></td><td class="mv__cell mv__cell--dim"><time datetime="2026-09-05">5</time></td></tr>
  </tbody>
</table>
<style>
.mv { border-collapse: collapse; width: 460px; font: 13px/1.3 system-ui, sans-serif; color: #241430; background: #FAF7F2; table-layout: fixed; }
.mv__caption { text-align: left; font-weight: 700; font-size: 15px; padding-bottom: 10px; }
.mv th, .mv td { text-align: center; padding: 10px 4px; border: 1px solid #24143014; position: relative; }
.mv th { font-weight: 600; color: #24143099; }
.mv[data-density="Compact"] th, .mv[data-density="Compact"] td { padding: 5px 4px; }
.mv__cell--dim { color: #24143055; }
.mv__cell--today time { font-weight: 800; }
.mv__today-dot { display: block; width: 5px; height: 5px; border-radius: 999px; background: var(--accent); margin: 3px auto 0; border: 1px solid #241430; }
.mv__cell--selected { background: var(--accent); outline: 2px solid #241430; outline-offset: -2px; border-radius: 4px; }
.mv__event-dot { display: block; width: 4px; height: 4px; border-radius: 999px; background: #E8A020; margin: 3px auto 0; }
.mv[data-weekend="false"] th:first-child, .mv[data-weekend="false"] td:first-child,
.mv[data-weekend="false"] th:last-child, .mv[data-weekend="false"] td:last-child { display: none; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
</style>

tailwind

<table class="border-collapse w-[460px] font-sans text-[13px] text-[#241430] bg-[#FAF7F2] mv-tw table-fixed" data-density="Comfortable" data-weekend="true">
  <caption class="text-left font-bold text-[15px] pb-2.5">August 2026</caption>
  <thead>
    <tr>
      <th scope="col" class="font-semibold text-[#241430]/60 text-center p-2.5 border border-[#24143014]">Sun</th>
      <th scope="col" class="font-semibold text-[#241430]/60 text-center p-2.5 border border-[#24143014]">Mon</th>
      <th scope="col" class="font-semibold text-[#241430]/60 text-center p-2.5 border border-[#24143014]">Tue</th>
      <th scope="col" class="font-semibold text-[#241430]/60 text-center p-2.5 border border-[#24143014]">Wed</th>
      <th scope="col" class="font-semibold text-[#241430]/60 text-center p-2.5 border border-[#24143014]">Thu</th>
      <th scope="col" class="font-semibold text-[#241430]/60 text-center p-2.5 border border-[#24143014]">Fri</th>
      <th scope="col" class="font-semibold text-[#241430]/60 text-center p-2.5 border border-[#24143014]">Sat</th>
    </tr>
  </thead>
  <tbody>
    <tr><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-07-26">26</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-07-27">27</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-07-28">28</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-07-29">29</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-07-30">30</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-07-31">31</time></td><td class="mvtw-cell"><time datetime="2026-08-01">1</time></td></tr>
    <tr><td class="mvtw-cell"><time datetime="2026-08-02">2</time></td><td class="mvtw-cell"><time datetime="2026-08-03">3</time></td><td class="mvtw-cell"><time datetime="2026-08-04">4</time></td><td class="mvtw-cell mvtw-cell--event"><time datetime="2026-08-05">5</time><span class="mvtw-event-dot" aria-hidden="true"></span></td><td class="mvtw-cell"><time datetime="2026-08-06">6</time></td><td class="mvtw-cell"><time datetime="2026-08-07">7</time></td><td class="mvtw-cell"><time datetime="2026-08-08">8</time></td></tr>
    <tr><td class="mvtw-cell"><time datetime="2026-08-09">9</time></td><td class="mvtw-cell mvtw-cell--selected" aria-current="date"><time datetime="2026-08-10">10</time></td><td class="mvtw-cell"><time datetime="2026-08-11">11</time></td><td class="mvtw-cell mvtw-cell--event"><time datetime="2026-08-12">12</time><span class="mvtw-event-dot" aria-hidden="true"></span></td><td class="mvtw-cell"><time datetime="2026-08-13">13</time></td><td class="mvtw-cell"><time datetime="2026-08-14">14</time></td><td class="mvtw-cell"><time datetime="2026-08-15">15</time></td></tr>
    <tr><td class="mvtw-cell"><time datetime="2026-08-16">16</time></td><td class="mvtw-cell"><time datetime="2026-08-17">17</time></td><td class="mvtw-cell mvtw-cell--today"><time datetime="2026-08-18">18</time><span class="mvtw-today-dot" aria-hidden="true"></span><span class="sr-only"> (today)</span></td><td class="mvtw-cell"><time datetime="2026-08-19">19</time></td><td class="mvtw-cell mvtw-cell--event"><time datetime="2026-08-20">20</time><span class="mvtw-event-dot" aria-hidden="true"></span></td><td class="mvtw-cell"><time datetime="2026-08-21">21</time></td><td class="mvtw-cell"><time datetime="2026-08-22">22</time></td></tr>
    <tr><td class="mvtw-cell"><time datetime="2026-08-23">23</time></td><td class="mvtw-cell"><time datetime="2026-08-24">24</time></td><td class="mvtw-cell"><time datetime="2026-08-25">25</time></td><td class="mvtw-cell"><time datetime="2026-08-26">26</time></td><td class="mvtw-cell mvtw-cell--event"><time datetime="2026-08-27">27</time><span class="mvtw-event-dot" aria-hidden="true"></span></td><td class="mvtw-cell"><time datetime="2026-08-28">28</time></td><td class="mvtw-cell"><time datetime="2026-08-29">29</time></td></tr>
    <tr><td class="mvtw-cell"><time datetime="2026-08-30">30</time></td><td class="mvtw-cell"><time datetime="2026-08-31">31</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-09-01">1</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-09-02">2</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-09-03">3</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-09-04">4</time></td><td class="mvtw-cell mvtw-cell--dim"><time datetime="2026-09-05">5</time></td></tr>
  </tbody>
</table>
<style>
.mv-tw td, .mv-tw th { position: relative; text-align: center; padding: 10px 4px; border: 1px solid #24143014; }
.mv-tw[data-density="Compact"] th, .mv-tw[data-density="Compact"] td { padding: 5px 4px; }
.mvtw-cell--dim { color: #24143055; }
.mvtw-cell--today time { font-weight: 800; }
.mvtw-today-dot { display: block; width: 5px; height: 5px; border-radius: 999px; background: #A8E6C1; margin: 3px auto 0; border: 1px solid #241430; }
.mvtw-cell--selected { background: #A8E6C1; outline: 2px solid #241430; outline-offset: -2px; border-radius: 4px; }
.mvtw-event-dot { display: block; width: 4px; height: 4px; border-radius: 999px; background: #E8A020; margin: 3px auto 0; }
.mv-tw[data-weekend="false"] th:first-child, .mv-tw[data-weekend="false"] td:first-child,
.mv-tw[data-weekend="false"] th:last-child, .mv-tw[data-weekend="false"] td:last-child { display: none; }
</style>

react

export function MonthView({
  month = "August 2026",
  density = "Comfortable",
  showWeekend = true,
  showEventDots = true,
  accent = "#A8E6C1",
}) {
  const TODAY = "2026-08-18";
  const SELECTED = "2026-08-10";
  const EVENT_DAYS = new Set(["2026-08-05", "2026-08-12", "2026-08-20", "2026-08-27"]);
  const weeks = [
    [{ day: 26, iso: "2026-07-26", dim: true }, { day: 27, iso: "2026-07-27", dim: true }, { day: 28, iso: "2026-07-28", dim: true }, { day: 29, iso: "2026-07-29", dim: true }, { day: 30, iso: "2026-07-30", dim: true }, { day: 31, iso: "2026-07-31", dim: true }, { day: 1, iso: "2026-08-01", dim: false }],
    [{ day: 2, iso: "2026-08-02", dim: false }, { day: 3, iso: "2026-08-03", dim: false }, { day: 4, iso: "2026-08-04", dim: false }, { day: 5, iso: "2026-08-05", dim: false }, { day: 6, iso: "2026-08-06", dim: false }, { day: 7, iso: "2026-08-07", dim: false }, { day: 8, iso: "2026-08-08", dim: false }],
    [{ day: 9, iso: "2026-08-09", dim: false }, { day: 10, iso: "2026-08-10", dim: false }, { day: 11, iso: "2026-08-11", dim: false }, { day: 12, iso: "2026-08-12", dim: false }, { day: 13, iso: "2026-08-13", dim: false }, { day: 14, iso: "2026-08-14", dim: false }, { day: 15, iso: "2026-08-15", dim: false }],
    [{ day: 16, iso: "2026-08-16", dim: false }, { day: 17, iso: "2026-08-17", dim: false }, { day: 18, iso: "2026-08-18", dim: false }, { day: 19, iso: "2026-08-19", dim: false }, { day: 20, iso: "2026-08-20", dim: false }, { day: 21, iso: "2026-08-21", dim: false }, { day: 22, iso: "2026-08-22", dim: false }],
    [{ day: 23, iso: "2026-08-23", dim: false }, { day: 24, iso: "2026-08-24", dim: false }, { day: 25, iso: "2026-08-25", dim: false }, { day: 26, iso: "2026-08-26", dim: false }, { day: 27, iso: "2026-08-27", dim: false }, { day: 28, iso: "2026-08-28", dim: false }, { day: 29, iso: "2026-08-29", dim: false }],
    [{ day: 30, iso: "2026-08-30", dim: false }, { day: 31, iso: "2026-08-31", dim: false }, { day: 1, iso: "2026-09-01", dim: true }, { day: 2, iso: "2026-09-02", dim: true }, { day: 3, iso: "2026-09-03", dim: true }, { day: 4, iso: "2026-09-04", dim: true }, { day: 5, iso: "2026-09-05", dim: true }],
  ];
  const pad = density === "Compact" ? "5px 4px" : "10px 4px";
  const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  return (
    <table style={{ borderCollapse: "collapse", width: 460, font: "13px/1.3 system-ui, sans-serif", color: "#241430", background: "#FAF7F2", tableLayout: "fixed" }}>
      <caption style={{ textAlign: "left", fontWeight: 700, fontSize: 15, paddingBottom: 10 }}>{month}</caption>
      <thead>
        <tr>
          {days.map((d, i) => (
            (showWeekend || (i !== 0 && i !== 6)) &&
            <th key={d} scope="col" style={{ fontWeight: 600, color: "#24143099", textAlign: "center", padding: pad, border: "1px solid #24143014" }}>{d}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {weeks.map((week, wi) => (
          <tr key={wi}>
            {week.map((c, ci) => {
              if (!showWeekend && (ci === 0 || ci === 6)) return null;
              const isToday = c.iso === TODAY;
              const isSelected = c.iso === SELECTED;
              const hasEvent = EVENT_DAYS.has(c.iso);
              return (
                <td key={c.iso} aria-current={isSelected ? "date" : undefined}
                  style={{ position: "relative", textAlign: "center", padding: pad, border: "1px solid #24143014",
                    color: c.dim ? "#24143055" : "#241430",
                    background: isSelected ? accent : "transparent",
                    outline: isSelected ? "2px solid #241430" : "none", outlineOffset: -2, borderRadius: isSelected ? 4 : 0 }}>
                  <time dateTime={c.iso} style={{ fontWeight: isToday ? 800 : 400 }}>{c.day}</time>
                  {isToday && <span aria-hidden="true" style={{ display: "block", width: 5, height: 5, borderRadius: 999, background: accent, margin: "3px auto 0", border: "1px solid #241430" }} />}
                  {isToday && <span className="sr-only" style={{ position: "absolute", width: 1, height: 1, overflow: "hidden" }}> (today)</span>}
                  {hasEvent && showEventDots && <span aria-hidden="true" style={{ display: "block", width: 4, height: 4, borderRadius: 999, background: "#E8A020", margin: "3px auto 0" }} />}
                </td>
              );
            })}
          </tr>
        ))}
      </tbody>
    </table>
  );
}