diff --git a/addon/components/o-s-s/calendar.hbs b/addon/components/o-s-s/calendar.hbs
new file mode 100644
index 000000000..4c57f51e3
--- /dev/null
+++ b/addon/components/o-s-s/calendar.hbs
@@ -0,0 +1,60 @@
+<div class="oss-calendar">
+  <div class="calendar-header fx-row fx-gap-px-3">
+    {{#if (eq this.currentCalendarView "month")}}
+      <OSS::Button @icon="fa-left" {{on "click" this.previousMonth}} />
+      <h2 {{on "click" this.showMonthsView}}>{{this.currentMonthName}} {{this.currentYear}}</h2>
+      <OSS::Button @icon="fa-right" {{on "click" this.nextMonth}} />
+    {{else}}
+      <div>
+        {{log this.yearsRange}}
+        <OSS::Select @value={{this.currentYear}} @items={{this.yearsRange}} @onChange={{this.changeYear}}>
+          <:selected as |option|>
+            <span value="{{this.currentYear}}" style="color:blue">{{this.currentYear}}</span>
+          </:selected>
+          <:option as |year|>
+            {{log year}}
+            <span value="{{year}}" selected={{eq year this.currentYear}}>{{year}}</span>
+          </:option>
+        </OSS::Select>
+      </div>
+    {{/if}}
+  </div>
+
+  {{#if (eq this.currentCalendarView "month")}}
+    <div class="calendar-table">
+      <div class="calendar-weekdays">
+        {{#each this.weekDays as |day|}}
+          <div class="calendar-weekday">{{day}}</div>
+        {{/each}}
+      </div>
+
+      <div class="calendar-days">
+        {{#each this.calendarDays as |week|}}
+          <div class="calendar-week">
+            {{#each week as |dayObj|}}
+              {{log dayObj}}
+              <div
+                class="calendar-day
+                  {{if (not dayObj.isCurrentMonth) 'opacified'}}
+                  {{if dayObj.isToday 'highlight'}}
+                  {{if dayObj.isSelected 'selected'}}"
+                {{on "click" (fn this.selectDate dayObj)}}
+              >
+                {{dayObj.day}}
+              </div>
+            {{/each}}
+          </div>
+        {{/each}}
+      </div>
+    </div>
+
+  {{else if (eq this.currentCalendarView "months")}}
+    <div class="months-picker">
+      {{#each this.monthsOfYear as |month index|}}
+        <div class="month-item" {{on "click" (fn this.selectMonth index)}}>
+          {{month}}
+        </div>
+      {{/each}}
+    </div>
+  {{/if}}
+</div>
diff --git a/addon/components/o-s-s/calendar.ts b/addon/components/o-s-s/calendar.ts
new file mode 100644
index 000000000..a92154d94
--- /dev/null
+++ b/addon/components/o-s-s/calendar.ts
@@ -0,0 +1,116 @@
+import Component from '@glimmer/component';
+import { tracked } from '@glimmer/tracking';
+import { action } from '@ember/object';
+import moment, { type Moment } from 'moment';
+
+enum CalendarViewtype {
+  month = 'month',
+  months = 'months',
+  year = 'year'
+}
+
+export default class CalendarComponent extends Component {
+  @tracked currentDate: Moment = moment();
+  @tracked selectedDay: Moment | null = null;
+  @tracked currentCalendarView: CalendarViewtype = CalendarViewtype.month;
+
+  get yearsRange(): number[] {
+    const currentYear = moment().year();
+    const startYear = currentYear - 20;
+    const endYear = currentYear + 20;
+    return Array.from({ length: endYear - startYear + 1 }, (v, i) => startYear + i);
+  }
+
+  get weekDays(): string[] {
+    return moment.weekdaysShort();
+  }
+
+  get currentMonthName(): string {
+    return this.currentDate.format('MMMM');
+  }
+
+  get currentYear(): number {
+    return this.currentDate.year();
+  }
+
+  get today(): number | null {
+    const today = moment();
+    return today.isSame(this.currentDate, 'month') ? today.date() : null;
+  }
+
+  get monthsOfYear(): string[] {
+    return moment.months();
+  }
+
+  get calendarDays() {
+    const startOfMonth = this.currentDate.clone().startOf('month');
+    const endOfMonth = this.currentDate.clone().endOf('month');
+    const startOfCalendar = startOfMonth.clone().startOf('week');
+    const endOfCalendar = endOfMonth.clone().endOf('week');
+    const today = moment();
+
+    const days = [];
+    let currentDay = startOfCalendar.clone();
+
+    while (currentDay.isBefore(endOfCalendar)) {
+      const week = [];
+      for (let i = 0; i < 7; i++) {
+        week.push({
+          day: currentDay.date(),
+          isCurrentMonth: currentDay.isSame(this.currentDate, 'month'),
+          isToday: currentDay.isSame(today, 'day'),
+          isSelected: this.selectedDay?.isSame(currentDay, 'day')
+        });
+        currentDay.add(1, 'day');
+      }
+      days.push(week);
+    }
+
+    return days;
+  }
+
+  @action
+  selectDate(dayObj: { day: number; isCurrentMonth: boolean; isToday: boolean; isSelected: boolean }) {
+    if (dayObj.isCurrentMonth) {
+      this.selectedDay = this.currentDate.clone().date(dayObj.day);
+    } else if (dayObj.day > 15) {
+      this.previousMonth();
+      this.selectedDay = this.currentDate.clone().endOf('month').date(dayObj.day);
+    } else {
+      this.nextMonth();
+      this.selectedDay = this.currentDate.clone().startOf('month').date(dayObj.day);
+    }
+
+    console.log(this.selectedDay);
+  }
+
+  @action
+  previousMonth() {
+    this.currentDate = this.currentDate.clone().subtract(1, 'month');
+    this.selectedDay = null;
+  }
+
+  @action
+  nextMonth() {
+    this.currentDate = this.currentDate.clone().add(1, 'month');
+    this.selectedDay = null;
+  }
+
+  @action
+  showMonthsView() {
+    this.currentCalendarView = CalendarViewtype.months;
+  }
+
+  @action
+  selectMonth(monthIndex: number) {
+    this.currentDate = this.currentDate.clone().month(monthIndex);
+    this.currentCalendarView = CalendarViewtype.month;
+  }
+
+  @action
+  changeYear(event: Event) {
+    console.log(event);
+    const value = event as unknown as number;
+    this.currentDate = this.currentDate.clone().year(value);
+  }
+}
diff --git a/app/components/o-s-s/calendar.js b/app/components/o-s-s/calendar.js
new file mode 100644
index 000000000..568126b54
--- /dev/null
+++ b/app/components/o-s-s/calendar.js
@@ -0,0 +1 @@
+export { default } from '@upfluence/oss-components/components/o-s-s/calendar';
diff --git a/app/styles/molecules/calendar.less b/app/styles/molecules/calendar.less
new file mode 100644
index 000000000..8b2a2f41b
--- /dev/null
+++ b/app/styles/molecules/calendar.less
@@ -0,0 +1,129 @@
+.oss-calendar {
+  font-family: Arial, sans-serif;
+  max-width: 400px;
+  margin: 20px auto;
+  border: 1px solid #ccc;
+  border-radius: 8px;
+  padding: 10px;
+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+  .oss-select-container {
+    width: 120px;
+  }
+}
+
+.calendar-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+}
+
+.calendar-header h2 {
+  font-size: 1.5rem;
+  font-weight: bold;
+  margin: 0;
+}
+
+.calendar-table {
+  display: grid;
+  grid-template-rows: auto 1fr;
+}
+
+.calendar-weekdays {
+  display: grid;
+  grid-template-columns: repeat(7, 1fr); /* 7 columns for 7 days */
+  text-align: center;
+  margin-bottom: 5px;
+  font-weight: bold;
+  font-size: 0.9rem;
+  background-color: #f7f7f7;
+  border-bottom: 1px solid #ccc;
+}
+
+.calendar-weekday {
+  padding: 10px 0;
+  border-right: 1px solid #ccc;
+}
+
+.calendar-weekday:last-child {
+  border-right: none;
+}
+
+.calendar-days {
+  display: grid;
+  grid-template-columns: repeat(7, 1fr);
+  gap: 2px;
+}
+
+.calendar-week {
+  display: contents;
+}
+
+.calendar-day {
+  padding: 10px;
+  text-align: center;
+  cursor: pointer;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+  transition: background-color 0.2s, color 0.2s;
+}
+
+.calendar-day:hover {
+  background-color: #f0f0f0;
+}
+
+.calendar-day.selected {
+  background-color: var(--color-primary-500);
+  color: white;
+}
+
+.calendar-day.today {
+  background-color: #ffeeba;
+  font-weight: bold;
+}
+
+.calendar-day.opacified {
+  opacity: 0.4;
+}
+
+.months-picker {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  gap: 10px;
+  padding: 10px;
+}
+
+.month-item {
+  padding: 15px;
+  text-align: center;
+  cursor: pointer;
+  background-color: #fff;
+  border: 1px solid var(--color-gray-50);
+  border-radius: 4px;
+  transition: background-color 0.2s;
+}
+
+.month-item:hover {
+  background-color: #f0f0f0;
+}
+
+.calendar-day.highlight {
+  background-color: lighten(@upf-primary-orange, 40%);
+  color: white;
+  font-weight: bold;
+  border: 1px solid lighten(@upf-primary-orange, 40%);
+}
+
+.calendar-day.selected {
+  background-color: var(--color-primary-500);
+  color: white;
+  font-weight: bold;
+  border: 1px solid #007bff;
+}
+
+@media (max-width: 400px) {
+  .calendar-day {
+    padding: 5px;
+  }
+}
diff --git a/app/styles/oss-components.less b/app/styles/oss-components.less
index c5b6356b3..3260ecc34 100644
--- a/app/styles/oss-components.less
+++ b/app/styles/oss-components.less
@@ -50,6 +50,7 @@
 @import 'molecules/togglable-section';
 @import 'molecules/password-input';
 @import 'molecules/avatar-group';
+@import 'molecules/calendar';
 @import 'organisms/table';
 @import 'organisms/dialog';
 @import 'organisms/modal-dialog';
diff --git a/package.json b/package.json
index 686cfb5b4..c208bba5a 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
     "ember-truth-helpers": "^3.1.1",
     "ion-rangeslider": "^2.3.1",
     "money-formatter": "^0.1.4",
+    "moment": "^2.29.4",
     "resolve": "^1.22.8"
   },
   "peerDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 13d1ba5f0..c26476591 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -62,6 +62,9 @@ dependencies:
   ion-rangeslider:
     specifier: ^2.3.1
     version: 2.3.1(jquery@3.7.1)
+  moment:
+    specifier: ^2.29.4
+    version: 2.30.1
   money-formatter:
     specifier: ^0.1.4
     version: 0.1.4
@@ -10520,7 +10523,7 @@ packages:
     resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==}
     engines: {node: '>= 4.0'}
     os: [darwin]
-    deprecated: The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2
+    deprecated: Upgrade to fsevents v2 to mitigate potential security issues
     requiresBuild: true
     dependencies:
       bindings: 1.5.0
@@ -13081,6 +13084,10 @@ packages:
     resolution: {integrity: sha512-IXnMcJ6ZyTuhRmJSjzvHSRhlVPiN9Jwc6e59V0bEJ0ba6OBeX2L0E+mRN1QseeOF4mM+F1Rit6Nh7o+rl2Yn/A==}
     engines: {node: '>0.9'}
 
+  /moment@2.30.1:
+    resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
+    dev: false
+
   /money-formatter@0.1.4:
     resolution: {integrity: sha512-0Mw0ztk+nPzyz+m/6lO/ejy2taFpG0OhHyBRRNdpn7EFd0eHHpa053/vNoBPqxVYWd77uJ8BjnVytKMhryMg5g==}
     dev: false
diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs
index e60a0032e..0b14d4208 100644
--- a/tests/dummy/app/templates/application.hbs
+++ b/tests/dummy/app/templates/application.hbs
@@ -29,6 +29,7 @@
   </OSS::Layout::Sidebar>
 
   <div style="width:100%; height:100vh; overflow: auto; background-color: var(--color-gray-50)">
+    <OSS::Calendar />
     <div class="fx-row fx-gap-px-10 margin-md">
       <OSS::Copy @value="I am the value copied" @inline={{true}} />
       <OSS::Copy @value="I am the value copied" />
@@ -1110,4 +1111,4 @@
     @icon="fa-circle-info"
     @skin="error"
   />
-{{/if}}
\ No newline at end of file
+{{/if}}
diff --git a/tests/integration/components/o-s-s/calendar-test.ts b/tests/integration/components/o-s-s/calendar-test.ts
new file mode 100644
index 000000000..0da362559
--- /dev/null
+++ b/tests/integration/components/o-s-s/calendar-test.ts
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | o-s-s/calendar', function (hooks) {
+  setupRenderingTest(hooks);
+
+  test('it renders', async function (assert) {
+    // Set any properties with this.set('myProperty', 'value');
+    // Handle any actions with this.set('myAction', function (val) { ... });
+
+    await render(hbs`<OSS::Calendar />`);
+
+    assert.dom().hasText('');
+
+    // Template block usage:
+    await render(hbs`
+      <OSS::Calendar>
+        template block text
+      </OSS::Calendar>
+    `);
+
+    assert.dom().hasText('template block text');
+  });
+});